コンポーネントをテストする受け入れテストがいくつかあります。各テストを個別に実行すると、問題なく合格します。ただし、テストを一緒に実行すると、以前のテストの値が保持されているため失敗します。
これが私のコードです:
filter-test.js
module('Integration - Filter', {
beforeEach: function() {
App = startApp();
server = setupPretender();
authenticateSession();
},
afterEach: function() {
Ember.run(App, 'destroy');
server.shutdown();
}
});
test('filters can be saved and selected via the dropdown', function(assert) {
visit('/status');
fillIn('.filter-status', 'Not Completed');
fillIn('.filter-id', '444');
andThen(function() {
assert.ok(find('.status-title').text().includes('2 of 7'), 'the new filter filters the results');
});
});
test('only saved filters can be edited', function(assert) {
visit('/status');
fillIn('.filter-id', 'not an id');
click('.update-filter');
andThen(function() {
assert.equal(find('.alert').text(), 'Not a Saved Filter×');
});
});
test('filter values can be cleared', function(assert) {
visit('/status');
fillIn('.filter-id', '444');
fillIn('.filter-status', 'Completed');
click('.clear-filters');
andThen(function() {
// this fails because `.filter-id` is set to 'not an id':
assert.equal(find('.filter-id').val(), '', 'filter for was reset to its initial value');
// this also fails because `.filter-status` is set to 'Not Completed':
assert.equal(find('.filter-status').val(), 'Everything', 'status dropdown was reset to its initial value');
});
});
ps-filter/component.js
export default Ember.Component.extend({
classNames: ['panel', 'panel-default', 'filter-panel'],
currentFilter: null,
initialValues: null,
didInsertElement: function() {
this.set('initialValues', Ember.copy(this.get('filterValues')));
},
actions: {
saveFilter: function(name) {
var filters = this._getFilterList();
var filterValues = this.get('filterValues');
if (!Ember.isEmpty(name)) {
filters[name] = filterValues;
this.sendAction('updateFilter', filters);
this.set('currentFilter', name);
}
},
updateFilter: function() {
var filterValues = this.get('filterValues');
var currentFilter = this.get('currentFilter')
var filters = this.get('userFilters');
filters[currentFilter] = filterValues;
this.sendAction('updateFilter', filters);
},
clearFilters: function() {
this.set('currentFilter', null);
this.set('filterValues', Ember.copy(this.get('initialValues')));
}
}
});
status/controller.js
export default Ember.ArrayController.extend({
filterValues: {
filterStatus: 'Everything',
filterId: 'id',
},
userFilters: Ember.computed.alias('currentUser.content.preferences.filters')
});
status/template.hbs
<div class="row">
{{ps-filter
filterValues=filterValues
userFilters=userFilters
updateFilter='updateFilter'
}}
</div>
私が集めたものからすると、前回のテストの残りに をinitialValues
設定しているようです。しかし、私はそれを元の状態に戻すはずfilterValues
だと思っていました。afterEach
コントローラーの値にリセットされない理由はありますか?
開発で実行すると、コンポーネントは正常に動作することに注意してください。
Ember インスペクターに表示される Ember バージョン:
Ember : 1.11.3
Ember Data : 1.0.0-beta.18
私は Ember CLI を実行しています0.2.7
。
編集
これはまったく問題ではないと思いますが、これが私の偽装者のセットアップです。
tests/helpers/setup-pretender.js
export default function setupPretender(attrs) {
var users = [
{
id: 1,
name: 'ttest',
preferences: null
}
];
var activities = [
{
id: 36874,
activity_identifier: '18291',
status: 'Complete'
}, {
id: 36873,
activity_identifier: '82012',
status: 'In Progress'
}, {
id: 35847,
activity_identifier: '189190',
status: 'In Progress'
}, {
id: 35858,
activity_identifier: '189076',
status: 'Not Started'
}, {
id: 382901,
activity_identifier: '182730',
status: 'Not Started'
}, {
id: 400293,
activity_identifier: '88392',
status: 'Complete'
}, {
id: 400402,
activity_identifier: '88547',
status: 'Complete'
}
];
return new Pretender(function() {
this.get('api/v1/users/:id', function(request) {
var user = users.find(function(user) {
if (user.id === parseInt(request.params.id, 10)) {
return user;
}
});
return [200, {"Content-Type": "application/json"}, JSON.stringify({user: user})];
});
this.get('api/v1/activities', function(request) {
return [200, {"Content-Type": "application/json"}, JSON.stringify({
activities: activities
})];
});
this.put('api/v1/users/:id', function(request) {
var response = Ember.$.parseJSON(request.requestBody);
response.user.id = parseInt(request.params.id, 10);
var oldUser = users.find(function(user) {
if (user.id === parseInt(request.params.id, 10)) {
return user;
}
});
var oldUserIndex = users.indexOf(oldUser);
if (oldUserIndex > -1) {
users.splice(oldUserIndex, 1);
users.push(response.user);
}
return [200, {"Content-Type": "application/json"}, JSON.stringify(response)];
});
});
}
テストを実行すると、値が前のテストの値にリセットされるため失敗します。たとえば、 を実行する'filter values can be cleared'
と、.filter-id
入力には からの同じ.filter-id
値が含まれ'only saved filter can be edited
ます。の値を に'only saved filters can be edited'
戻すと''
、'filter values can be cleared'
テストに合格します。
基本的に、コンポーネントはinitialValues
最初に要素を挿入するときにプロパティを設定します。プロパティのコピーに設定されているfilterValues
ため、コントローラーのfilterValues
プロパティに設定する必要があり、変更しないでください。ただし、変更されたfilterValues
プロパティは次のテストに引き継がれるようです。つまり、initialValues
再レンダリング時にその変更されたプロパティに設定されます。そのため、テストはテンプレートを再レンダリングしますが、コントローラーとコンポーネントで変更された値を保持します。
コントローラーでプロパティを作成し、それをコンポーネントに渡すことでテストを通過させることができますが、initialValues
それはコントローラーに重複したプロパティを持つことを意味します (filterValues
とinitialValues
は同じ値を持つため)。
コンポーネント内のユーザー レコードを変更することはできましたが、コントローラーまたはルーター内のレコードのみを変更することになっていると思いました。その上、afterEach
フックはアプリをリセットするはずではありませんか?