kaliber5 / ember-yadda-backup1 Goto Github PK
View Code? Open in Web Editor NEWAn opinionated way of adding Cucumber BDD to you app via Yadda
An opinionated way of adding Cucumber BDD to you app via Yadda
Path | Use | Default import must return |
---|---|---|
/tests/yadda/steps.js |
Step library to be used for feature files | A hash of opinionated steps |
/tests/yadda/steps/<my-steps>.js |
Custom step implementations | A hash of opinionated steps, to be composed into main steps.js |
/tests/yadda/dictionary.js |
Converters aka macros | An hash of string | Regexp | [string | RegExp, (string[]) => Promise<any> ] |
/tests/yadda/labels.js |
Custom labels for third-party selectors | An hash of string , e. g. {'Bootstrap-Primary-Button', '.btn-primary') |
/tests/yadda/annotations.js |
Annotations to setup features and scenarios | TBD |
Yadda has a weird API for defining the dictionary:
new Yadda.Dictionary()
.define('address', '$street, $postcode')
.define('street', /(\d+) (\w+))
.define('postcode', /((GIR &0AA)|((([A-PR-UWYZ][A-HK-Y]?[0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]))) &[0-9][ABD-HJLNP-UW-Z]{2}))/)
.define('num', /(\d+)/, Yadda.converters.integer)
.define('quantity', /(\d+) (\w+)/, (amount, units, cb) => {
cb(null, { amount: amount, units: units })
});
.define('user', '$user', (userName, cb) => {
fetch(`https://api.example.com/users/${userName}`).then(
(response) => cb(null, response.json()),
(e) => cb(e)
);
});
This Node-style callback is inconvenient and hard to type. Basically, you pass a callback that accepts a callback.
ember-yadda
uses a simplified way of defining the dictionary:
{
address: '$street, $postcode',
street: /(\d+) (\w+),
postcode: /((GIR &0AA)|((([A-PR-UWYZ][A-HK-Y]?[0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]))) &[0-9][ABD-HJLNP-UW-Z]{2}))/,
num: Yadda.converters.integer,
quantity: [
/(\d+) (\w+)/,
(amount, units) => ({ amount: amount, units: units })
],
user: [
'$user',
async (userName) => (await fetch(`https://api.example.com/users/${userName}`)).json()
]
}
Under the hood, ember-yadda
will convert these straightforward callbacks into Node-style supported by Yadda like this:
import opinionatedDictionary from '<my-app>/tests/yadda/dictionary';
function instantiateYaddaDictionary(opinionatedDictionary) {
const yaddaDictionary = new Yadda.Dictionary();
Object.entries(opinionatedDictionary).forEach(([macroName, macroDefinition]) => {
if (Array.isArray(macroDefinition)) {
const [pattern, converter] = macroDefinition;
yaddaDictionary.define(macroName, pattern, wrapConverterWithNodeStyle(converter));
} else {
yaddaDictionary.define(macroName, macroDefinition);
}
});
return yaddaDictionary;
}
function wrapConverterWithNodeStyle(converter) {
return (...args) => {
const cb = args.pop();
try {
const result = await converter(...args);
cb(null, result);
} catch (e) {
cb(e);
}
}
}
export default instantiateYaddaDictionary(opinionatedDictionary);
Now it is very convenient to define converter macros, but existing converters from Yadda.converters
are Node-style. I see three ways to resolve this:
When defining a macro using a Yadda.converters
converter, use an util on it so that it is wrapped with async/await that the addon supports.
E. g. instead of:
num: Yadda.converters.integer,
you would do:
num: converter(Yadda.converters.integer),
The downside of this approach is that a Node-style converter will be wrapped with async/await by the util and then wrapped again with Node-style by the addon.
Have wrapConverterWithNodeStyle
detect whether the converter is Node-style or async/await.
One way to do this would be to use introspection:
import introspect from 'introspect-fun'; // https://github.com/NicolasVargas/introspect-fun
function maybeWrapConverterWithNodeStyle(converter) {
return introspect(coverter).pop() === 'next'
? converter
: wrapConverterWithNodeStyle(converter);
}
The downside of this approach is that it's magical and unreliable, since it assumes that a node-style callback has its last argument called next
. It will fail both when a Yadda.converters
converter has the last argument called differently (currently not the case) and when an async/await converter has its last argument called next
.
There's also a performance implication, but it should be negligible.
Maybe there's another way to distinguish Node-style Yadda.converters
converters from async/await converters?
Simply port all six Yadda.converters
converters, so that either the ember-yadda
addon or a separate content-oriented addon offers async/await equivalents.
Downside: more work to do. I was gonna write "more maintenance", but after ensuring test coverage the code will not need to be revisited.
We'll also need to maintain compatibility with Yadda.converters
, but I doubt that they will stray far from what they currently are.
ember-cli-yadda
In the legacy ember-cli-yadda
, a test file generated from a feature file imports a matching steps file like this.
We could make this import conditional. If the steps file exists, run it using the legacy setup. Otherwise, use the new setup described above.
Within the steps file, the user has complete freedom. They can:
ember-cli-yadda
.ember-cli-yadda-opinionated
. This lets you use legacy ember-cli-yadda
steps and opinionated steps in the same feature.Previously, localizaton setup was happening in the app.
Due to drastically simplified design of addon's in-app files, the addon will have yadda.localisation.default
hardcoded.
I believe internationalized steps are a bad practice, so we should not bother making it configurable.
In future, if there's a feature request for supporting non-English locales, we'll be able to think about a way of making it configurable.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.