From d23d5bc966c6d2c633bfcc2fcf319e2b5d35bd3b Mon Sep 17 00:00:00 2001 From: John Bryson Date: Fri, 14 Feb 2020 09:43:24 -0500 Subject: [PATCH 1/5] fourteen-testing-api - During model transform preserve the argument passed to this.subject --- .../setup-model-test.input2.js | 14 ++++++++++++++ .../setup-model-test.output2.js | 12 ++++++++++++ fourteen-testing-api.js | 5 ++++- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 __testfixtures__/fourteen-testing-api/setup-model-test.input2.js create mode 100644 __testfixtures__/fourteen-testing-api/setup-model-test.output2.js diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test.input2.js b/__testfixtures__/fourteen-testing-api/setup-model-test.input2.js new file mode 100644 index 0000000..aac070d --- /dev/null +++ b/__testfixtures__/fourteen-testing-api/setup-model-test.input2.js @@ -0,0 +1,14 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupModelTest } from 'ember-mocha'; + +describe('Unit | Model | rental', function() { + setupModelTest('rental', { + needs: [] + }); + // Replace this with your real tests. + it('exists', function() { + let model = this.subject({num: 5, obj: {key: 'val'}, arr: [1,'two']}); + expect(model).to.be.ok; + }); +}); diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test.output2.js b/__testfixtures__/fourteen-testing-api/setup-model-test.output2.js new file mode 100644 index 0000000..c8bf012 --- /dev/null +++ b/__testfixtures__/fourteen-testing-api/setup-model-test.output2.js @@ -0,0 +1,12 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupTest } from 'ember-mocha'; + +describe('Unit | Model | rental', function() { + setupTest(); + // Replace this with your real tests. + it('exists', function() { + let model = this.owner.lookup('service:store').createRecord('rental', {num: 5, obj: {key: 'val'}, arr: [1,'two']}); + expect(model).to.be.ok; + }); +}); diff --git a/fourteen-testing-api.js b/fourteen-testing-api.js index a511cf3..eafceb8 100755 --- a/fourteen-testing-api.js +++ b/fourteen-testing-api.js @@ -502,6 +502,9 @@ module.exports = function(file, api) { ) ); } else if (subjectType === 'model') { + let createRecordArg = p.node.arguments[0] ? + p.node.arguments[0] : /* the argument provided to this.subject() */ + j.objectExpression([]) /* empty object expression {} */; p.replace( j.callExpression( j.memberExpression( @@ -516,7 +519,7 @@ module.exports = function(file, api) { ), // creating an empty object expression {} as the 2nd argument here // because setupModelTests shouldn't need store dependencies - [j.literal(subjectName), j.objectExpression([])].filter(Boolean) + [j.literal(subjectName), createRecordArg].filter(Boolean) ) ); } else { From 0a5eec73387a41e6f5996add22d2eb3b5d7d0516 Mon Sep 17 00:00:00 2001 From: John Bryson Date: Wed, 5 Feb 2020 00:03:25 -0500 Subject: [PATCH 2/5] Allow user to opt into wrapping a createModel with a runLoop to avoid errors when testing for older versions of Ember --- fourteen-testing-api.js | 42 ++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/fourteen-testing-api.js b/fourteen-testing-api.js index eafceb8..e527d61 100755 --- a/fourteen-testing-api.js +++ b/fourteen-testing-api.js @@ -1,8 +1,9 @@ "use strict"; -module.exports = function(file, api) { +module.exports = function(file, api, options) { const j = api.jscodeshift; const root = j(file.source); + const codeShiftOptions = options; const SETUP_TYPE_METHODS = ["setupComponentTest", "setupModelTest"]; @@ -502,11 +503,12 @@ module.exports = function(file, api) { ) ); } else if (subjectType === 'model') { - let createRecordArg = p.node.arguments[0] ? - p.node.arguments[0] : /* the argument provided to this.subject() */ - j.objectExpression([]) /* empty object expression {} */; - p.replace( - j.callExpression( + // this.subject({props}) => this.owner.lookup('service:store').createRecord({props}); + + let createRecordArg = p.node.arguments[0] || j.objectExpression([]), /* the argument provided to this.subject() OR empty object expression*/ + { wrapCreateModelWithRunLoop } = codeShiftOptions, + createRecordExpression = (createRecordArg) => { + return j.callExpression( j.memberExpression( j.callExpression( j.memberExpression( @@ -517,11 +519,33 @@ module.exports = function(file, api) { ), j.identifier('createRecord') ), - // creating an empty object expression {} as the 2nd argument here - // because setupModelTests shouldn't need store dependencies [j.literal(subjectName), createRecordArg].filter(Boolean) ) - ); + }, + runLoopExpression = (content) => { + return j.callExpression( + j.memberExpression( + j.identifier('Ember'), j.identifier('run') + ), [j.arrowFunctionExpression( + [], + content + )] + ) + }; + + if( wrapCreateModelWithRunLoop ){ + // If the user has opted into wrapping with run loop + p.replace( + runLoopExpression( + createRecordExpression(createRecordArg) + ) + ); + } else { + p.replace( + createRecordExpression(createRecordArg) + ); + } + } else { p.replace( j.callExpression( From 79b17a1038503b5d5d3c6ec065695292d0647ade Mon Sep 17 00:00:00 2001 From: John Bryson Date: Fri, 14 Feb 2020 10:24:55 -0500 Subject: [PATCH 3/5] Add test for wrapping model.createRecord with runloop --- ...l-test.input2.js => setup-model-test2.input.js} | 0 ...test.output2.js => setup-model-test2.output.js} | 0 .../setup-model-test3.output.js | 14 ++++++++++++++ ...-test3.wrapCreateModelWithRunLoop=true.input.js | 14 ++++++++++++++ __tests__/fourteen-testing-api-test.js | 14 +++++++++----- 5 files changed, 37 insertions(+), 5 deletions(-) rename __testfixtures__/fourteen-testing-api/{setup-model-test.input2.js => setup-model-test2.input.js} (100%) rename __testfixtures__/fourteen-testing-api/{setup-model-test.output2.js => setup-model-test2.output.js} (100%) create mode 100644 __testfixtures__/fourteen-testing-api/setup-model-test3.output.js create mode 100644 __testfixtures__/fourteen-testing-api/setup-model-test3.wrapCreateModelWithRunLoop=true.input.js diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test.input2.js b/__testfixtures__/fourteen-testing-api/setup-model-test2.input.js similarity index 100% rename from __testfixtures__/fourteen-testing-api/setup-model-test.input2.js rename to __testfixtures__/fourteen-testing-api/setup-model-test2.input.js diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test.output2.js b/__testfixtures__/fourteen-testing-api/setup-model-test2.output.js similarity index 100% rename from __testfixtures__/fourteen-testing-api/setup-model-test.output2.js rename to __testfixtures__/fourteen-testing-api/setup-model-test2.output.js diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test3.output.js b/__testfixtures__/fourteen-testing-api/setup-model-test3.output.js new file mode 100644 index 0000000..cc848c7 --- /dev/null +++ b/__testfixtures__/fourteen-testing-api/setup-model-test3.output.js @@ -0,0 +1,14 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupTest } from 'ember-mocha'; + +describe('Unit | Model | rental', function() { + setupTest(); + // Replace this with your real tests. + it('exists', function() { + let model = Ember.run( + () => this.owner.lookup('service:store').createRecord('rental', {num: 5, obj: {key: 'val'}, arr: [1,'two']}) + ); + expect(model).to.be.ok; + }); +}); diff --git a/__testfixtures__/fourteen-testing-api/setup-model-test3.wrapCreateModelWithRunLoop=true.input.js b/__testfixtures__/fourteen-testing-api/setup-model-test3.wrapCreateModelWithRunLoop=true.input.js new file mode 100644 index 0000000..aac070d --- /dev/null +++ b/__testfixtures__/fourteen-testing-api/setup-model-test3.wrapCreateModelWithRunLoop=true.input.js @@ -0,0 +1,14 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupModelTest } from 'ember-mocha'; + +describe('Unit | Model | rental', function() { + setupModelTest('rental', { + needs: [] + }); + // Replace this with your real tests. + it('exists', function() { + let model = this.subject({num: 5, obj: {key: 'val'}, arr: [1,'two']}); + expect(model).to.be.ok; + }); +}); diff --git a/__tests__/fourteen-testing-api-test.js b/__tests__/fourteen-testing-api-test.js index b89f9da..fbfefc2 100755 --- a/__tests__/fourteen-testing-api-test.js +++ b/__tests__/fourteen-testing-api-test.js @@ -13,15 +13,19 @@ describe('fourteen-testing-api', function() { .readdirSync(fixtureFolder) .filter(filename => /\.input\.js$/.test(filename)) .forEach(filename => { - let testName = filename.replace('.input.js', ''); - let inputPath = path.join(fixtureFolder, `${testName}.input.js`); - let outputPath = path.join(fixtureFolder, `${testName}.output.js`); + // filename format - the-test-name.option1=foo.option2=bar.inputX.js + + let testNameWithOptions = filename.replace('.input.js', ''), // the-test-name.option1=foo.option2=bar + codeshiftOptions = testNameWithOptions.split('.').slice(1).reduce((p,c) => {p[c.split('=')[0]] = c.split('=')[1]; return p;}, {}), // {option1:foo, option2:bar} + testName = testNameWithOptions.split('.')[0], // the-test-name + inputPath = path.join(fixtureFolder, filename), + outputPath = path.join(fixtureFolder, `${testName}.output.js`); describe(testName, function() { it('transforms correctly', function() { runInlineTest( FourteenTestingAPITransform, - {}, + codeshiftOptions, { source: fs.readFileSync(inputPath, 'utf8') }, fs.readFileSync(outputPath, 'utf8') ); @@ -30,7 +34,7 @@ describe('fourteen-testing-api', function() { it('is idempotent', function() { runInlineTest( FourteenTestingAPITransform, - {}, + codeshiftOptions, { source: fs.readFileSync(outputPath, 'utf8') }, fs.readFileSync(outputPath, 'utf8') ); From c55a636830e80030676176585f93d745711936cb Mon Sep 17 00:00:00 2001 From: John Bryson Date: Fri, 14 Feb 2020 10:39:25 -0500 Subject: [PATCH 4/5] Add documentation for the --wrapCreateModelWithRunLoop option --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 75a3c86..d3b5675 100755 --- a/README.md +++ b/README.md @@ -123,6 +123,15 @@ npx ember-test-helpers-codemod acceptance tests/acceptance npx ember-test-helpers-codemod native-dom tests ``` +## Codeshift Options +`--wrapCreateModelWithRunLoop=true` + +This option will wrap `createRecord` calls with a runLoop. This was needed in older versions of Ember to avoid this error: "You have turned on testing mode, which disabled the run-loop's autorun." +``` +let model = this.subject({a:'a'}); //before +let model = Ember.run(() => this.owner.lookup('service:store').createRecord('rental', {a:'a'})); //after +``` + License ------------------------------------------------------------------------------ ember-mocha-codemods is licensed under the [MIT License](LICENSE). From 62c459a58ed3fd5d2522787410e24ebf71078ec0 Mon Sep 17 00:00:00 2001 From: John Bryson Date: Fri, 14 Feb 2020 10:54:20 -0500 Subject: [PATCH 5/5] Remove misleading character in comment --- __tests__/fourteen-testing-api-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/fourteen-testing-api-test.js b/__tests__/fourteen-testing-api-test.js index fbfefc2..d573e24 100755 --- a/__tests__/fourteen-testing-api-test.js +++ b/__tests__/fourteen-testing-api-test.js @@ -13,7 +13,7 @@ describe('fourteen-testing-api', function() { .readdirSync(fixtureFolder) .filter(filename => /\.input\.js$/.test(filename)) .forEach(filename => { - // filename format - the-test-name.option1=foo.option2=bar.inputX.js + // filename format - the-test-name.option1=foo.option2=bar.input.js let testNameWithOptions = filename.replace('.input.js', ''), // the-test-name.option1=foo.option2=bar codeshiftOptions = testNameWithOptions.split('.').slice(1).reduce((p,c) => {p[c.split('=')[0]] = c.split('=')[1]; return p;}, {}), // {option1:foo, option2:bar}