Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
14 changes: 14 additions & 0 deletions __testfixtures__/fourteen-testing-api/setup-model-test2.input.js
Original file line number Diff line number Diff line change
@@ -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;
});
});
12 changes: 12 additions & 0 deletions __testfixtures__/fourteen-testing-api/setup-model-test2.output.js
Original file line number Diff line number Diff line change
@@ -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;
});
});
14 changes: 14 additions & 0 deletions __testfixtures__/fourteen-testing-api/setup-model-test3.output.js
Original file line number Diff line number Diff line change
@@ -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;
});
});
Original file line number Diff line number Diff line change
@@ -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;
});
});
14 changes: 9 additions & 5 deletions __tests__/fourteen-testing-api-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.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}
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')
);
Expand All @@ -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')
);
Expand Down
41 changes: 34 additions & 7 deletions fourteen-testing-api.js
Original file line number Diff line number Diff line change
@@ -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"];

Expand Down Expand Up @@ -502,8 +503,12 @@ module.exports = function(file, api) {
)
);
} else if (subjectType === 'model') {
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(
Expand All @@ -514,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), j.objectExpression([])].filter(Boolean)
[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(
Expand Down