The rules for resolving SIDs in COLLADA, and COLLADA FX SIDs in particular, are not very clear. With regard to COLLADA FX SIDs in particular, how do I know at which element to start the search for a particular SID? Consider, for example, the "texture" atttibute of a <texture> element:
<effect id="Scene_Material_fx">
<profile_COMMON>
<newparam sid="acorn_png_surface">
<surface type="2D">
<init_from>acorn_png_img</init_from>
</surface>
</newparam>
<newparam sid="acorn_png_sampler">
<sampler2D>
<source>acorn_png_surface</source>
</sampler2D>
</newparam>
<technique sid="default">
<phong>
...
<diffuse>
<texture texture="acorn_png_sampler" texcoord="diffuse_TEXCOORD"></texture>
</diffuse>
...
</phong>
</technique>
</profile_COMMON>
</effect>
I can find the SID referenced by <texture> if I start the search at <profile_COMMON>, which is the great-great-grandparent of the <texture> element that contains the reference, but I can also find it if I start searching from <effect>. How, then, is the starting element determined? Is it defined somewhere in the spec?
Does the spec provide a limit to how close to the document root an sid referenced by a particular <texture> element may be found? In the above example, could it possibly appear outside of <profile_COMMON>, such as inside its <effect> parent? Which is the "rootmost" element at which I am guaranteed to find the referenced sid by drilling down from that element?
Update: I have also posted this question in the COLLADA forums, so far with no response. I've decided that, for the time being, I shall simply assume the SID referenced by a <texture>'s "texture" attribute will always be found under <profile_COMMON>. If that's wrong it means my importer may fail on valid input, but the COLLADA community itself has offered no feedback on this so there's nothing I can do.
I can feel your pain ;-). Collada specs are really hard to understand.
As you can have params declared in <effect> scope (not only inside <profile> : Chapter 7 About parameters) you should look there too.
But. Judging from my experience exporters tends to have local params (under <profile>) so your way will work too.
This is an old question, but I believe the answer is that SID's are 'scoped id's' at the level of the parent ID. So you technically begin searching just under the element, and all sids are unique under that block.
That was always my understanding, anyway...
Related
I was wondering about some best practices regarding extraction of selectors to constants. As a general rule, it is usually recommended to extract magic numbers and string literals to constants so they can be reused, but I am not sure if this is really a good approach when dealing with selectors in Capybara.
At the moment, I have a file called "selectors.rb" which contains the selectors that I use. Here is part of it:
SELECTORS = {
checkout: {
checkbox_agreement: 'input#agreement-1',
input_billing_city: 'input#billing\:city',
input_billing_company: 'input#billing\:company',
input_billing_country: 'input#billing\:country_id',
input_billing_firstname: 'input#billing\:firstname',
input_billing_lastname: 'input#billing\:lastname',
input_billing_postcode: 'input#billing\:postcode',
input_billing_region: 'input#billing\:region_id',
input_billing_street1: 'input#billing\:street1',
....
}
In theory, I put my selectors in this file, and then I could do something like this:
find(SELECTORS[:checkout][:input_billing_city]).click
There are several problems with this:
If I want to know the selector that is used, I have to look it up
If I change the name in selectors.rb, I could forget to change it somewhere else in the file which will result in find(nil).click
With the example above, I can't use this selector with fill_in(SELECTORS[:checkout][:input_billing_city]), because it requires an ID, name or label
There are probably a few more problems with that, so I am considering to get rid of the constants. Has anyone been in a similar spot? What is a good way to deal with this situation?
Someone mentioned the SitePrism gem to me: https://github.com/natritmeyer/site_prism
A Page Object Model DSL for Capybara
SitePrism gives you a simple, clean and semantic DSL for describing
your site using the Page Object Model pattern, for use with Capybara
in automated acceptance testing.
It is very helpful in that regard and I have adjusted my code accordingly.
Looks like the documentation is stable. But I am a bit frustrated about its conventions. For example, what is the field name in the following screenshot? Any one help point where the guideline for reading the documentation is?
name in this case is an optional name you can use for the port. You use it like this:
var port = chrome.runtime.connect({name:"testName"});
After that, port.name would be "testName".
connectInfo is defined to be an object meaning that any field listed indented under it, like name is, is a part of it.
This is PascalCase: SomeSymbol
This is camelCase: someSymbol
This is snake_case: some_symbol
So my questions is whether there is a widely accepted name for this: some-symbol? It's commonly used in url's.
There isn't really a standard name for this case convention, and there is disagreement over what it should be called.
That said, as of 2019, there is a strong case to be made that kebab-case is winning:
https://trends.google.com/trends/explore?date=all&q=kebab-case,spinal-case,lisp-case,dash-case,caterpillar-case
spinal-case is a distant second, and no other terms have any traction at all.
Additionally, kebab-case has entered the lexicon of several javascript code libraries, e.g.:
https://lodash.com/docs/#kebabCase
https://www.npmjs.com/package/kebab-case
https://v2.vuejs.org/v2/guide/components-props.html#Prop-Casing-camelCase-vs-kebab-case
However, there are still other terms that people use. Lisp has used this convention for decades as described in this Wikipedia entry, so some people have described it as lisp-case. Some other forms I've seen include caterpillar-case, dash-case, and hyphen-case, but none of these is standard.
So the answer to your question is: No, there isn't a single widely-accepted name for this case convention analogous to snake_case or camelCase, which are widely-accepted.
It's referred to as kebab-case. See lodash docs.
It's also sometimes known as caterpillar-case
This is the most famous case and It has many names
kebab-case: It's the name most adopted by official software
caterpillar-case
dash-case
hyphen-case or hyphenated-case
lisp-case
spinal-case
css-case
slug-case
friendly-url-case
As the character (-) is referred to as "hyphen" or "dash", it seems more natural to name this "dash-case", or "hyphen-case" (less frequently used).
As mentioned in Wikipedia, "kebab-case" is also used. Apparently (see answer) this is because the character would look like a skewer... It needs some imagination though.
Used in lodash lib for example.
Recently, "dash-case" was used by
Angular (https://angular.io/guide/glossary#case-types)
NPM modules
https://www.npmjs.com/package/case-dash (removed ?)
https://www.npmjs.com/package/dasherize
Adding the correct link here Kebab Case
which is All lowercase with - separating words.
I've always called it, and heard it be called, 'dashcase.'
There is no standardized name.
Libraries like jquery and lodash refer it as kebab-case. So does Vuejs javascript framework. However, I am not sure whether it's safe to declare that it's referred as kebab-case in javascript world.
I've always known it as kebab-case.
On a funny note, I've heard people call it a SCREAM-KEBAB when all the letters are capitalized.
Kebab Case Warning
I've always liked kebab-case as it seems the most readable when you need whitespace. However, some programs interpret the dash as a minus sign, and it can cause problems as what you think is a name turns into a subtraction operation.
first-second // first minus second?
ten-2 // ten minus two?
Also, some frameworks parse dashes in kebab cased property. For example, GitHub Pages uses Jekyll, and Jekyll parses any dashes it finds in an md file. For example, a file named 2020-1-2-homepage.md on GitHub Pages gets put into a folder structured as \2020\1\2\homepage.html when the site is compiled.
Snake_case vs kebab-case
A safer alternative to kebab-case is snake_case, or SCREAMING_SNAKE_CASE, as underscores cause less confusion when compared to a minus sign.
I'd simply say that it was hyphenated.
Worth to mention from abolish:
https://github.com/tpope/vim-abolish/blob/master/doc/abolish.txt#L152
dash-case or kebab-case
In Salesforce, It is referred as kebab-case. See below
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.js_props_names
Here is a more recent discombobulation. Documentation everywhere in angular JS and Pluralsight courses and books on angular, all refer to kebab-case as snake-case, not differentiating between the two.
Its too bad caterpillar-case did not stick because snake_case and caterpillar-case are easily remembered and actually look like what they represent (if you have a good imagination).
My ECMAScript proposal for String.prototype.toKebabCase.
String.prototype.toKebabCase = function () {
return this.valueOf().replace(/-/g, ' ').split('')
.reduce((str, char) => char.toUpperCase() === char ?
`${str} ${char}` :
`${str}${char}`, ''
).replace(/ * /g, ' ').trim().replace(/ /g, '-').toLowerCase();
}
This casing can also be called a "slug", and the process of turning a phrase into it "slugify".
https://hexdocs.pm/slugify/Slug.html
I am using watir-webdriver (0.5.3) in a Cucumber (1.1.9) test. I am attempting to verify the text value of an <acronym> tag. The code is legacy, and there are plans to change it to a <div> or <span> tag, but in the mean time I have to deal with it. I first attempted:
#browser.acronym(:id => /expense_code(.*)/).text
I received the following error:
NoMethodError: undefined method `acronym' for #<Watir::Browser:0x33e9940>
I poked around in the Watir code to see how tag objects were being created, and found that they seem to be dynamically created based on the HTML5 spec, but then I also found a comment in element.rb stating that they are no longer being created from the spec. At any rate, I couldn't see an easy way to inherit a <span> object and call it an <acronym> object. So, I looked into alternatives, and found the element object.
#browser.element(:id => /expense_code(.*)/).text
This code works, but it takes about a minute to traverse my page. I'm stuck with the regex for now, as the tag id is actually dynamically generated and I don't currently have a way to figure out those values. This is what the tag actually looks like:
<acronym class="editable select fillwith:exp_codes default:E100"
title="Expense Code: Expenses" id="expense_code114_582_10777">
E100 </acronym>
I would appreciate any thoughts on how I can improve the performance of my test.
Is that class name predictable? could you construct that from a set part plus the text you are about to validate (it's the same in your example above) and go that way?
acronym = 'E100'
browser.element(:class, 'editable select fillwith:exp_codes default:#{acronym}'.text.should == acronym
Does using XPath to limit the elements to just acronym tags help performance?
#browser.element(:xpath, "//acronym[contains(#id, 'expense_code')]")
UPDATE: As Chuck mentioned, CSS-Selector is also an option:
#browser.element(:css => "acronym[id^=expense_code]")
I was recently stealing logic from Watir 1.6.5 to make custom locators/collections for my page objects and I noticed in the Watir::TaggedElementLocator, it kind of supports any method that the element supports. Noticing in Watir-Webdriver that elements have a tag_name() method, I thought I would try the same and it looks like it works.
So you can use tag_name as a locator by doing:
#browser.element(:tag_name => 'acronym', :id => /expense_code(.*)/).text
I'm not sure what order the locators get run in, so since the regex is expensive, it might be faster to get all the acronym elements and then find the one with the right ID:
#browser.elements(:tag_name, 'acronym').find{ |acronym|
acronym.id =~ /expense_code(.*)/
}.text
While I think it makes the code look better, unfortunately I'm not sure if its any faster. I am guessing the performance of each will depend on the specific page layout being tested.
I'm not sure what the proper etiquette is here, but this is the answer I came up with using Chuck's reply and feedback from jarib in the #watir IRC chat. With all my examples, expense_code = 'E100'.
#browser.element(:tag_name => "acronym",
:class => "default:#{expense_code}").text
The above code works at a very reasonable speed and doesn't require an xpath. It is a shortening of the following code:
#browser.element(:tag_name => "acronym",
:class => "editable select fillwith:exp_codes default:#{expense_code}").text
I learned that I didn't need to pass the whole string. Anything in a class delimited by a space is dealt with gracefully by watir. I adapted that code from this xpath:
#browser.element(:xpath => "//acronym[contains(#class,
\'editable select fillwith:exp_codes default:#{expense_code}\')]").text
The gotcha in that code above was needing to escape out the ' around the class values so that it would evaluate correctly.
Just searching for the class (code below) did not work. I have no idea why. I did notice that it pounded the database with requests. Whatever it was doing, the page didn't like it. Though the reason it was trying multiple times is I slipped a wait_until_present in there.
#browser.element(:class, "editable select fillwith:exp_codes
default:#{expense_code}").text
Thanks for the help. :)
NOTE: The scenario is using 2 entity framework models to sync data between 2 databases, but I'd imagine this is applicable to other scenarios. One could try tackling this on the EF side as well (like in this SO question) but I wanted to see if AutoMapper could handle it out-of-the-box
I'm trying to figure out if AutoMapper can (easily :) compare the source and dest values (when using it to sync to an existing object) and do the copy only if the values are different (based on Equals by default, potentially passing in a Func, like if I decided to do String.Equals with StringComparison.OrdinalIgnoreCase for some particular pair of values). At least for my scenario, I'm fine if it's restricted to just the TSource == TDest case (I'll be syncing over int's, string's, etc, so I don't think I'll need any type converters involved)
Looking through the samples and tests, the closest thing seems to be conditional mapping (src\UnitTests\ConditionalMapping.cs), and I would use the Condition overload that takes the Func (since the other overload isn't sufficient, as we need the dest information too). That certainly looks on the surface like it would work fine (I haven't actually used it yet), but I would end up with specifying this for every member (although I'm guessing I could define a small number of actions/methods and at least reuse them instead of having N different lambdas).
Is this the simplest available route (outside of changing AutoMapper) for getting a 'only copy if source and dest values are different' or is there another way I'm not seeing? If it is the simplest route, has this already been done before elsewhere? It certainly feels like I'm likely reinventing a wheel here. :)
Chuck Norris (formerly known as Omu? :) already answered this, but via comments, so just answering and accepting to repeat what he said.
#James Manning you would have to inherit ConventionInjection, override
the Match method and write there return c.SourceProp.Name =
c.TargetProp.Name && c.SourceProp.Value != c.TargetProp.Value and
after use it target.InjectFrom(source);
In my particular case, since I had a couple of other needs for it anyway, I just customized the EF4 code generation to include the check for whether the new value is the same as the current value (for scalars) which takes care of the issue with doing a 'conditional' copy - now I can use Automapper or ValueInject or whatever as-is. :)
For anyone interested in the change, when you get the default *.tt file, the simplest way to make this change (at least that I could tell) was to find the 2 lines like:
if (ef.IsKey(primitiveProperty))
and change both to be something like:
if (ef.IsKey(primitiveProperty) || true) // we always want the setter to include checking for the target value already being set