typescript - How to wait for a callback to be executed inside a AngularJS directive unit test? -



typescript - How to wait for a callback to be executed inside a AngularJS directive unit test? -

i have simple directive works fine (written typescript not matter) allows content of files uploaded via <input type="file"> , html5 file api.

the utilize simple:

<body ng-controller="myctrl ctrl"> <input type="file" file-read="ctrl.readinputfile(data)"> </body>

callback readinputfile() beingness called files content.

interface ifilereadscope extends angular.iscope { fileread(data: any): void; } class fileread implements angular.idirective { restrict = 'a'; scope = { fileread: '&' }; link = (scope: ifilereadscope, element: angular.iaugmentedjquery) => { element.on('change', (e: event) => { allow files: filelist = (<htmlinputelement> e.target).files; (let = 0; < files.length; i++) { allow file = files[i]; allow reader = new filereader(); reader.onload = (e: event) => { scope.$apply(() => { scope.fileread({data: (<filereader> e.target).result}); }); }; reader.readastext(file); } }); }; static factory(): angular.idirectivefactory { allow directive = () => new fileread(); homecoming directive; } } app.directive('fileread', fileread.factory());

and here test it:

describe('fileread', () => { beforeeach(module('app')); allow $compile: angular.icompileservice; allow scope: any; beforeeach(inject((_$compile_, _$rootscope_) => { $compile = _$compile_; scope = _$rootscope_.$new(); })); function compiletemplate(template: string): angular.iaugmentedjquery { var el = $compile(angular.element(template))(scope); scope.$digest(); homecoming el; } it('should phone call callback each time file has been read', () => { allow el = compiletemplate( '<input type="file" file-read="readinputfile(data)">' ); allow files = new array<string>(); scope.readinputfile = (data: any) => { files.push(data); }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest(); // fails because not wait scope.readinputfile() called expect(files.length).toequal(2); expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1'); }); });

the problem don't know how wait scope.readinputfile() callback executed.

i've tried scope.$digest(), $rootscope.$digest(), $apply, jasmine spyon... i've checked how popular directives that. seems nobody "that" :/

any idea?

edit:

thanks hooray im helping , matho, here 2 possible solutions using jasmine 2:

let files: array<string>; beforeeach((done) => { allow el = compiletemplate( '<input type="file" file-read="readinputfile(data)">' ); files = new array<string>(); scope.readinputfile = (data: any) => { files.push(data); if (files.length === 2) done(); }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest(); }); it('should phone call callback each time file has been read', () => { expect(files.length).toequal(2); expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1'); });

and more elegant 1 in case:

it('should phone call callback each time file has been read', (done) => { allow el = compiletemplate( '<input type="file" file-read="readinputfile(data)">' ); allow files = new array<string>(); scope.readinputfile = (data: any) => { files.push(data); if (files.length === 2) { expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1'); done(); } }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest(); });

if scope.fileread() not executed within directive, test fail:

failed fileread should phone call callback each time file has been read error: timeout - async callback not invoked within timeout specified jasmine.default_timeout_interval.

so if code breaks unit test fail => job done :)

what version of jasmine using?

if it's 1.3, can utilize waitsfor , runs wait period of time assert on specs:

so

let files = new array<string>(); scope.readinputfile = (data: any) => { files.push(data); }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest();

becomes

let files = new array<string>(); runs(function() { scope.readinputfile = (data: any) => { files.push(data); }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest(); });

and

expect(files.length).toequal(2); expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1');

becomes

waitsfor(function() { expect(files.length).toequal(2); expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1'); }, "failure message", time_in_milliseconds);

if you're using jasmine 2.0, can utilize done function:

you'd move code you're trying test (and set code depends on) beforeeach, phone call async code there, notify framework async operation done calling done method when async code finishes. specs run automatically run after done called. have never used before (i'm still on 1.3) , don't utilize angular nor karma, i'm in bit of unfamiliar territory.

according this answer, beforeeach function should this:

beforeeach(function(done) { inject((_$compile_: angular.icompileservice, _$rootscope_: angular.irootscopeservice) => { $compile = _$compile_; $rootscope = _$rootscope_; scope = $rootscope.$new(); }); allow el = compiletemplate('<input type="file" file-read="readinputfile(data)">'); allow files = new array<string>(); scope.readinputfile = (data: any) => { files.push(data); }; el.triggerhandler({ type: 'change', target: { files: [ new blob(['data0']), new blob(['data1']) ] } }); scope.$digest(); done(); });

and assertion should like:

it('should phone call callback each time file has been read filereader', (done) => { expect(files.length).toequal(2); expect(files[0]).toequal('data0'); expect(files[1]).toequal('data1'); done(); });

again, don't utilize angular, typescript, or karma, might need tweak this. general idea; set up, run async code, phone call done in set up, run assertions, phone call done in spec.

angularjs typescript jasmine karma-jasmine

Comments

Post a Comment

Popular posts from this blog

design - Custom Styling Qt Quick Controls -

Unable to remove the www from url on https using .htaccess -