'use strict'; describe('angular.scenario.ObjectModel', function() { var model; var runner; var spec, step; function buildSpec(id, name, definitions) { var spec = { id: id, name: name, definition: { name: definitions.shift() } }; var currentDef = spec.definition; forEach(definitions, function(defName) { currentDef.parent = { name: defName }; currentDef = currentDef.parent; }); return spec; } function buildStep(name, line) { return { name: name || 'test step', line: function() { return line || ''; } }; } beforeEach(function() { spec = buildSpec(1, 'test spec', ['describe 1']); step = buildStep(); runner = new angular.scenario.testing.MockRunner(); model = new angular.scenario.ObjectModel(runner); }); it('should value default empty value', function() { expect(model.value).toEqual({ name: '', children: [] }); }); it('should add spec and create describe blocks on SpecBegin event', function() { runner.emit('SpecBegin', buildSpec(1, 'test spec', ['describe 2', 'describe 1'])); expect(model.value.children['describe 1']).toBeDefined(); expect(model.value.children['describe 1'].children['describe 2']).toBeDefined(); expect(model.value.children['describe 1'].children['describe 2'].specs['test spec']).toBeDefined(); }); it('should set fullDefinitionName on SpecBegin event', function() { runner.emit('SpecBegin', buildSpec(1, 'fake spec', ['describe 2'])); var spec = model.getSpec(1); expect(spec.fullDefinitionName).toBeDefined(); expect(spec.fullDefinitionName).toEqual('describe 2'); }); it('should set fullDefinitionName on SpecBegin event (join more names by space)', function() { runner.emit('SpecBegin', buildSpec(1, 'fake spec', ['describe 2', 'describe 1'])); var spec = model.getSpec(1); expect(spec.fullDefinitionName).toEqual('describe 1 describe 2'); }); it('should add step to spec on StepBegin', function() { runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].steps.length).toEqual(1); }); it('should update spec timer duration on SpecEnd event', function() { runner.emit('SpecBegin', spec); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].duration).toBeDefined(); }); it('should update step timer duration on StepEnd event', function() { runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].steps[0].duration).toBeDefined(); }); it('should set spec status on SpecEnd to success if no status set', function() { runner.emit('SpecBegin', spec); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('success'); }); it('should set status to error after SpecError', function() { runner.emit('SpecBegin', spec); runner.emit('SpecError', spec, 'error'); expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('error'); }); it('should set spec status to failure if step fails', function() { runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, 'error'); runner.emit('StepEnd', spec, step); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('failure'); }); it('should set spec status to error if step errors', function() { runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepError', spec, step, 'error'); runner.emit('StepEnd', spec, step); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, 'error'); runner.emit('StepEnd', spec, step); runner.emit('SpecEnd', spec); expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('error'); }); describe('events', function() { var Spec = angular.scenario.ObjectModel.Spec, Step = angular.scenario.ObjectModel.Step, callback; beforeEach(function() { callback = jasmine.createSpy('listener'); }); it('should provide method for registering a listener', function() { expect(model.on).toBeDefined(); expect(model.on instanceof Function).toBe(true); }); it('should forward SpecBegin event', function() { model.on('SpecBegin', callback); runner.emit('SpecBegin', spec); expect(callback).toHaveBeenCalled(); }); it('should forward SpecBegin event with ObjectModel.Spec as a param', function() { model.on('SpecBegin', callback); runner.emit('SpecBegin', spec); expect(callback.mostRecentCall.args[0] instanceof Spec).toBe(true); expect(callback.mostRecentCall.args[0].name).toEqual(spec.name); }); it('should forward SpecError event', function() { model.on('SpecError', callback); runner.emit('SpecBegin', spec); runner.emit('SpecError', spec, {}); expect(callback).toHaveBeenCalled(); }); it('should forward SpecError event with ObjectModel.Spec and error as a params', function() { var error = {}; model.on('SpecError', callback); runner.emit('SpecBegin', spec); runner.emit('SpecError', spec, error); var param = callback.mostRecentCall.args[0]; expect(param instanceof Spec).toBe(true); expect(param.name).toEqual(spec.name); expect(param.status).toEqual('error'); expect(param.error).toBe(error); }); it('should forward SpecEnd event', function() { model.on('SpecEnd', callback); runner.emit('SpecBegin', spec); runner.emit('SpecEnd', spec); expect(callback).toHaveBeenCalled(); }); it('should forward SpecEnd event with ObjectModel.Spec as a param', function() { model.on('SpecEnd', callback); runner.emit('SpecBegin', spec); runner.emit('SpecEnd', spec); expect(callback.mostRecentCall.args[0] instanceof Spec).toBe(true); expect(callback.mostRecentCall.args[0].name).toEqual(spec.name); }); it('should forward StepBegin event', function() { model.on('StepBegin', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); expect(callback).toHaveBeenCalled(); }); it('should forward StepBegin event with Spec and Step as params', function() { model.on('StepBegin', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); var params = callback.mostRecentCall.args; expect(params[0] instanceof Spec).toBe(true); expect(params[0].name).toEqual(spec.name); expect(params[1] instanceof Step).toBe(true); }); it('should forward StepError event', function() { model.on('StepError', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepError', spec, step, {}); expect(callback).toHaveBeenCalled(); }); it('should forward StepError event with Spec, Step and error as params', function() { var error = {}; model.on('StepError', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepError', spec, step, error); var params = callback.mostRecentCall.args; expect(params[0] instanceof Spec).toBe(true); expect(params[0].name).toEqual(spec.name); expect(params[1] instanceof Step).toBe(true); expect(params[1].status).toEqual('error'); expect(params[2]).toBe(error); }); it('should forward StepFailure event', function() { model.on('StepFailure', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, {}); expect(callback).toHaveBeenCalled(); }); it('should forward StepFailure event with Spec, Step and error as params', function() { var error = {}; model.on('StepFailure', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, error); var params = callback.mostRecentCall.args; expect(params[0] instanceof Spec).toBe(true); expect(params[0].name).toEqual(spec.name); expect(params[1] instanceof Step).toBe(true); expect(params[1].status).toEqual('failure'); expect(params[2]).toBe(error); }); it('should forward StepEnd event', function() { model.on('StepEnd', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); expect(callback).toHaveBeenCalled(); }); it('should forward StepEnd event with Spec and Step as params', function() { model.on('StepEnd', callback); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepEnd', spec, step); var params = callback.mostRecentCall.args; expect(params[0] instanceof Spec).toBe(true); expect(params[0].name).toEqual(spec.name); expect(params[1] instanceof Step).toBe(true); }); it('should forward RunnerEnd event', function() { model.on('RunnerEnd', callback); runner.emit('RunnerEnd'); expect(callback).toHaveBeenCalled(); }); it('should set error of first failure', function() { var error = 'first-error', step2 = buildStep(); model.on('SpecEnd', function(spec) { expect(spec.error).toBeDefined(); expect(spec.error).toBe(error); }); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, error); runner.emit('StepBegin', spec, step2); runner.emit('StepFailure', spec, step2, 'second-error'); runner.emit('SpecEnd', spec); }); it('should set line number of first failure', function() { var step = buildStep('fake', 'first-line'), step2 = buildStep('fake2', 'second-line'); model.on('SpecEnd', function(spec) { expect(spec.line).toBeDefined(); expect(spec.line).toBe('first-line'); }); runner.emit('SpecBegin', spec); runner.emit('StepBegin', spec, step); runner.emit('StepFailure', spec, step, null); runner.emit('StepBegin', spec, step2); runner.emit('StepFailure', spec, step2, null); runner.emit('SpecEnd', spec); }); }); });