I'm attempting to write a test for my Yeoman generator which calls a command-line utility to generate some files in the folder I'm scaffolding. I've seen various examples of how to set a timeout to wait for a function to finish but am struggling to get it to work locally.
Here's my test:
describe('Should properly scaffold with config for Spring and wsdl2rest', function () {
before(function () {
basicProps.name = 'MyAppMock';
basicProps.package = 'com.generator.mock';
basicProps.camelVersion = '2.18.2';
basicProps.camelDSL = 'spring';
var wsdlPath = path.join(__dirname, '../test/address.wsdl');
basicProps.wsdl = wsdlPath;
basicProps.outdirectory = 'src/main/java';
return helpers.run(path.join(__dirname, '../app'))
.inTmpDir(function (dir) {
var done = this.async(); // `this` is the RunContext object.
fs.copy(path.join(__dirname, '../templates'), dir, done);
basicProps.outdirectory = path.join(dir, 'src/main/java');
})
.withOptions({ wsdl2rest: true })
.withPrompts({ name: basicProps.name })
.withPrompts({ camelVersion: basicProps.camelVersion })
.withPrompts({ camelDSL: basicProps.camelDSL })
.withPrompts({ package: basicProps.package })
.withPrompts({ wsdl: basicProps.wsdl })
.withPrompts({ outdirectory: basicProps.outdirectory })
.toPromise();
});
it('Should create the basic structure two ways', function () {
assert.file('pom.xml');
assert.file('README.md');
assert.file('src/main/resources/META-INF/spring/camel-context.xml');
assert.file('src/main/resources/META-INF/spring/camel-context-rest.xml')
});
});
The problem is that the command-line executable is finishing AFTER the test to see if the files that it generates are there so I'm getting:
Creating wsdl2rest java output directory
calling: java -jar C:\Users\brianf\Documents\GitHub\generator-camel-project-fork\app\wsdl2rest\target\wsdl2rest-impl-fatjar-0.1.3-SNAPSHOT.jar --wsdl file:///C:/Users/brianf/Documents/GitHub/generator-camel-project-fork/test/address.wsdl --out C:\Users\brianf\AppData\Local\Temp\8d84f15024327cbe792407e1294ab46a5b4a1080\src\main\java --camel-context C:\Users\brianf\AppData\Local\Temp\8d84f15024327cbe792407e1294ab46a5b4a1080\src\main\resources\META-INF\spring\camel-context-rest.xml
1) Should create the basic structure two ways
11 passing (411ms)
1 failing
1) generator-camel:wsdl2rest
Should properly scaffold with config for Spring and wsdl2rest
Should create the basic structure two ways:
AssertionError [ERR_ASSERTION]: src/main/resources/META-INF/spring/camel-context-rest.xml, no such file or directory
+ expected - actual
-false
+true
at convertArgs.forEach.file (node_modules\yeoman-assert\index.js:56:12)
at Array.forEach (<anonymous>)
at Function.assert.file (node_modules\yeoman-assert\index.js:54:26)
at Context.<anonymous> (test\app.js:206:14)
stdout: Retrieving document at 'file:/C:/Users/brianf/Documents/GitHub/generator-camel-project-fork/test/address.wsdl'.
stderr: log4j:WARN No appenders could be found for logger (org.jboss.fuse.wsdl2rest.impl.WSDLProcessorImpl).
stderr: log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
wsdl2rest generated artifacts successfully
What's the secret to getting this thing to wait? I'm positive I'm missing something obvious, but I'm mostly a Java programmer not JavaScript and struggling a bit with some of the asynchronous aspects of the language.
Thanks in advance!
Update: Though it has been suggested that I use Mocha's asynchronous code options (https://mochajs.org/#asynchronous-code) I am having a difficult time wrestling those concepts into the test I have written and could use some additional help if anybody has tackled this with Yeoman generator testing?
Looking at the mocha docs here - https://mochajs.org/#asynchronous-hooks
It seems as though you might need to place the "before" outside your "describe". Alternatively you can wrap the "it" inside another "describe".
Thanks to @Evan, we found a solution yesterday...
There are two parts - one was the fact that the method we created to actually call our Java jar wasn't returning a Promise... so we changed it to:
console.log('calling: ' + cmdString);
return new Promise((resolve, reject) => {
const wsdl2rest = exec(cmdString);
wsdl2rest.stdout.on('data', function (data) {
console.log(`stdout: ${data}`);
});
wsdl2rest.stderr.on('data', function (data) {
console.log(`stderr: ${data}`);
});
wsdl2rest.on('close', function (code) {
if (code === 0) {
console.log(`wsdl2rest generated artifacts successfully`);
resolve()
} else {
reject()
console.log(`stderr: ${code}`);
console.log(`wsdl2rest did not generate artifacts successfully - please check the log file for details`);
}
});
})
And we changed the test to be:
describe('generator-camel:wsdl2rest', function () {
describe('Should properly scaffold with config for Spring and wsdl2rest', function () {
it('Should create the basic structure two ways', function () {
basicProps.name = 'MyAppMock';
basicProps.package = 'com.generator.mock';
basicProps.camelVersion = '2.18.2';
basicProps.camelDSL = 'spring';
var wsdlPath = path.join(__dirname, '../test/address.wsdl');
basicProps.wsdl = wsdlPath;
basicProps.outdirectory = 'src/main/java';
return helpers.run(path.join(__dirname, '../app'))
.inTmpDir(function (dir) {
var done = this.async(); // `this` is the RunContext object.
fs.copy(path.join(__dirname, '../templates'), dir, done);
basicProps.outdirectory = path.join(dir, 'src/main/java');
})
.withOptions({ wsdl2rest: true })
.withPrompts({ name: basicProps.name })
.withPrompts({ camelVersion: basicProps.camelVersion })
.withPrompts({ camelDSL: basicProps.camelDSL })
.withPrompts({ package: basicProps.package })
.withPrompts({ wsdl: basicProps.wsdl })
.withPrompts({ outdirectory: basicProps.outdirectory })
.toPromise()
.then(() => {
assert.file('pom.xml');
assert.file('README.md');
assert.file('src/main/resources/META-INF/spring/camel-context.xml');
assert.file('src/main/resources/META-INF/spring/camel-context-rest.xml')
});
});
});
With all of this in place, we're able to run toPromise and it waits to do the asserts.
Thank you for the guidance Evan!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With