フィルタの変更に関する情報を格納するコードがあります。 ブラウザで$watch
値を変更するたびにコールバックが発生します。 しかし、ジャスミン/カルマテストでそれを複製しようとすると、最初に変更した直後に起動します。コンソールで
コントローラ
var tableFilter = this
;
var init0 = true
;
$scope.$watch('tableFilter.config.period', function() {
console.log('watch');
if (!init0) {
console.log('set dirty');
tbFilterConfig.set('pristine', false);
tbFilterConfig.setDirty('period');
}
init0 = false;
});
テスト
describe('$scope $watch', function() {
it('should add period to dirty after second change', function() {
$scope.$apply(console.log(1), controller.config.period = 'test');
expect(tbFilterConfigObj.get('dirty')).toEqual([]);
$scope.$apply(console.log(2), controller.config.period = 'test2');
expect(tbFilterConfigObj.get('dirty')).toEqual([ 'period' ]);
});
});
出力:
LOG: 1
LOG: 'watch'
LOG: 2
PhantomJS 1.9.8 (Windows 8 0.0.0) Controller: TableFilterCtrl $scope $watch should add period to dirty after second change FAILED
Expected [ ] to equal [ 'period' ].
at C:/Projects/trackback-network-insight-ui/test/spec/controllers/table_filter.js:74
しかし、ブラウザで:
setTimeout(function () {
$scope.$apply(console.log(1), tableFilter.config.period = 'test');
$scope.$apply(console.log(2), tableFilter.config.period = 'test2');
}, 1000);
通知:
LOG: watch
LOG: 1
LOG: watch
LOG: set dirty
LOG: 2
LOG: watch
LOG: set dirty
これは予想される動作です。
私のテストで何が間違っていますか?前もって感謝します!
EDIT
フルコントローラコード:
angular.module('insightApp')
.controller('TableFilterCtrl', [ '$rootScope', 'tbConfig', '$scope', '$http', 'API_PATH', 'uiAlerts', 'tbFilterConfig',
function ($rootScope, tbConfig, $scope, $http, API_PATH, uiAlerts, tbFilterConfig) {
var tableFilter = this
, newData = {}
;
/* EXTRACT INITIAL DATA OR LOAD DATA IF TYPE OF DATA IS STRING */
/* FETCH !!SELECT!! DATA FROM API */
function fetchData(url, name) {
return $http.post(API_PATH + url, tbFilterConfig.get())
.success(function (data) {
newData[ name ] = data;
})
.error(function (error) {
uiAlerts.set({
error: 'Ooops! We were unable to get filter data.'
});
console.error(error);
});
}
tableFilter.filters = tbConfig.get('filters');
tableFilter.reports = tbConfig.get('reports');
tableFilter.config = tbFilterConfig.getRaw();
/* RESET VALUES OF ALL DEPENDENT FILTERS */
function resetDependent(name) {
var filters = tbConfig.get('filters')
;
filters.forEach(function (filter) {
if (filter.dependencies && filter.dependencies.indexOf(name) > -1) {
if (tbFilterConfig.get(filter.key) !== filter.defaultVal) {
tbFilterConfig.set(filter.key, filter.defaultVal);
tbFilterConfig.setDirty(filter.key);
}
}
});
}
/* GET INITIAL DATA FOR SELECT OPTIONS */
tableFilter.getData = function (name, data, defaultVal) {
if (!(name in newData)) {
newData[ name ] = [];
if (typeof data === 'string') {
fetchData(data, name);
} else if (typeof data === 'object') {
newData[ name ] = data;
} else {
console.error('Unexpected data type:', typeof data, data);
}
if (!tbFilterConfig.get(name)) {
tbFilterConfig.set(name, defaultVal);
}
var init = true;
$scope.$watch('tableFilter.config.' + name, function() {
if (!init) {
resetDependent(name);
tbFilterConfig.set('pristine', false);
tbFilterConfig.setDirty(name);
}
init = false;
});
}
return newData[ name ];
};
/* WATCH FIXED PROPERTIES: PERIOD, DATE_FROM, DATE_TO */
var init0 = true
, init1 = true
, init2 = true
;
$scope.$watch('tableFilter.config.period', function() {
if (!init0) {
tbFilterConfig.set('pristine', false);
tbFilterConfig.setDirty('period');
}
init0 = false;
});
/* WATCH FIXED PROPERTIES DATE_FORM */
$scope.$watch('tableFilter.config.date_from', function() {
if (!init1) {
tbFilterConfig.set('pristine', false);
tbFilterConfig.setDirty('date_from');
}
init1 = false;
});
/* WATCH FIXED PROPERTIES DATE_TO */
$scope.$watch('tableFilter.config.date_to', function() {
if (!init2) {
tbFilterConfig.set('pristine', false);
tbFilterConfig.setDirty('date_to');
}
init2 = false;
});
/* UPDATE FILTER DATA */
tableFilter.updateSelectData = function (url, name, dependencies) {
if (typeof url === 'string') {
var touched = false;
/* CHECK IF DEPENDENCIES CHANGED */
for (var i = 0; i < dependencies.length; i++) {
if (tableFilter.config.dirty.indexOf(dependencies[ i ]) > -1) {
touched = true;
break;
}
}
/* IF DEPENDENCIES CHANGED GET NEW DATA */
if (touched) {
return fetchData(url, name);
}
}
};
} ]);
及び試験:
describe('Controller: TableFilterCtrl', function() {
// load the controller's module
beforeEach(function() {
module('insightApp');
});
var controller
, $scope
, alerts
, tbFilterConfigObj
;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope, uiAlerts, tbFilterConfig) {
tbFilterConfigObj = tbFilterConfig;
$scope = $rootScope.$new();
alerts = uiAlerts;
controller = $controller('TableFilterCtrl', {
$scope: $scope
});
$scope.$apply();
}));
describe('$scope $watch', function() {
it('should add period to dirty after second change', function() {
$scope.$apply(console.log(1), controller.config.period = 'test');
expect(tbFilterConfigObj.get('dirty')).toEqual([]);
$scope.$apply(console.log(2), controller.config.period = 'test2');
expect(tbFilterConfigObj.get('dirty')).toEqual([ 'period' ]);
});
});
})。
EDIT2
私は、コードの品質のために申し訳ないが、それはまだ生産ではありません。
setTimeout(function(){expect(tbFilterConfigObj.get( 'dirty')))を使用して2番目のテストをラップする.toEqual(['period']); done();};テストでdoneパラメータを渡すことを忘れないでください。 – srinivasan
@srinivasanどのように私の問題を解決すると思いますか? –