UNPKG

@bigtest/mirage

Version:

A client-side server to develop, test and prototype your app.

347 lines (278 loc) 7.89 kB
import { Factory, trait } from '@bigtest/mirage'; import {module, test} from 'qunit'; module('Unit | Factory'); test('it exists', function(assert) { assert.ok(Factory); }); test('the base class builds empty objects', function(assert) { let f = new Factory(); let data = f.build(); assert.deepEqual(data, {}); }); test('a noop extension builds empty objects', function(assert) { let EmptyFactory = Factory.extend(); let f = new EmptyFactory(); let data = f.build(); assert.deepEqual(data, {}); }); test('it works with strings, numbers and booleans', function(assert) { let AFactory = Factory.extend({ name: 'Sam', age: 28, alive: true }); let f = new AFactory(); let data = f.build(); assert.deepEqual(data, { name: 'Sam', age: 28, alive: true }); }); test('it supports inheritance', function(assert) { let PersonFactory = Factory.extend({ species: 'human' }); let ManFactory = PersonFactory.extend({ gender: 'male' }); let SamFactory = ManFactory.extend({ name: 'Sam' }); let p = new PersonFactory(); let m = new ManFactory(); let s = new SamFactory(); assert.deepEqual(p.build(), { species: 'human' }); assert.deepEqual(m.build(), { species: 'human', gender: 'male' }); assert.deepEqual(s.build(), { species: 'human', gender: 'male', name: 'Sam' }); }); test('it can use sequences', function(assert) { let PostFactory = Factory.extend({ likes(i) { return 5 * i; } }); let p = new PostFactory(); let post1 = p.build(1); let post2 = p.build(2); assert.deepEqual(post1, { likes: 5 }); assert.deepEqual(post2, { likes: 10 }); }); test('it can reuse static properties', function(assert) { let BazFactory = Factory.extend({ foo: 5, bar(i) { return this.foo * i; } }); let b = new BazFactory(); let baz1 = b.build(1); let baz2 = b.build(2); assert.deepEqual(baz1, { foo: 5, bar: 5 }); assert.deepEqual(baz2, { foo: 5, bar: 10 }); }); test('it can reuse dynamic properties', function(assert) { let BazFactory = Factory.extend({ foo(i) { return 5 * i; }, bar() { return this.foo * 2; } }); let b = new BazFactory(); let baz1 = b.build(1); let baz2 = b.build(2); assert.deepEqual(baz1, { foo: 5, bar: 10 }); assert.deepEqual(baz2, { foo: 10, bar: 20 }); }); test('it can have dynamic properties that depend on another', function(assert) { let BazFactory = Factory.extend({ name() { return 'foo'; }, bar() { return this.name.substr(1); } }); let b = new BazFactory(); let baz1 = b.build(1); assert.deepEqual(baz1, { name: 'foo', bar: 'oo' }); }); test('it can reference properties out of order', function(assert) { let BazFactory = Factory.extend({ bar() { return this.foo + 2; }, baz: 6, foo(i) { return this.baz * i; } }); let b = new BazFactory(); let baz1 = b.build(1); let baz2 = b.build(2); assert.deepEqual(baz1, { baz: 6, foo: 6, bar: 8 }); assert.deepEqual(baz2, { baz: 6, foo: 12, bar: 14 }); }); test('it can reference multiple properties in any order', function(assert) { let FooFactory = Factory.extend({ foo() { return this.bar + this.baz; }, bar: 6, baz: 10 }); let BarFactory = Factory.extend({ bar: 6, foo() { return this.bar + this.baz; }, baz: 10 }); let BazFactory = Factory.extend({ bar: 6, baz: 10, foo() { return this.bar + this.baz; } }); let Foo = new FooFactory(); let Bar = new BarFactory(); let Baz = new BazFactory(); let foo = Foo.build(1); let bar = Bar.build(1); let baz = Baz.build(1); assert.deepEqual(foo, { foo: 16, bar: 6, baz: 10 }); assert.deepEqual(bar, { foo: 16, bar: 6, baz: 10 }); assert.deepEqual(baz, { foo: 16, bar: 6, baz: 10 }); }); test('it can reference properties on complex object', function(assert) { let AbcFactory = Factory.extend({ a(i) { return this.b + i; }, b() { return this.c + 1; }, c() { return this.f + 1; }, d(i) { return this.e + i; }, e() { return this.c + 1; }, f: 1, g: 2, h: 3 }); let b = new AbcFactory(); let abc1 = b.build(1); let abc2 = b.build(2); assert.deepEqual(abc1, { a: 4, b: 3, c: 2, d: 4, e: 3, f: 1, g: 2, h: 3 }); assert.deepEqual(abc2, { a: 5, b: 3, c: 2, d: 5, e: 3, f: 1, g: 2, h: 3 }); }); test('throws meaningfull exception on circular reference', function(assert) { let BazFactory = Factory.extend({ bar() { return this.foo; }, foo() { return this.bar; } }); let b = new BazFactory(); assert.throws(function() { b.build(1); }, function(e) { return e.toString() === 'Error: Cyclic dependency in properties ["foo","bar"]'; }); }); test('#build skips invoking `afterCreate`', function(assert) { let skipped = true; let PostFactory = Factory.extend({ afterCreate() { skipped = false; } }); let factory = new PostFactory(); let post = factory.build(0); assert.ok(skipped, 'skips invoking `afterCreate`'); assert.equal( typeof post.afterCreate, 'undefined', 'does not build `afterCreate` attribute' ); }); test('extractAfterCreateCallbacks returns all afterCreate callbacks from factory with the base one being first', function(assert) { let PostFactory = Factory.extend({ published: trait({ afterCreate() { return 'from published'; } }), withComments: trait({ afterCreate() { return 'from withComments'; } }), otherTrait: trait({}), afterCreate() { return 'from base'; } }); let callbacks = PostFactory.extractAfterCreateCallbacks(); assert.equal(callbacks.length, 3); assert.deepEqual(callbacks.map((cb) => cb()), ['from base', 'from published', 'from withComments']); }); test('extractAfterCreateCallbacks filters traits from which the afterCreate callbacks will be extracted from', function(assert) { let PostFactory = Factory.extend({ published: trait({ afterCreate() { return 'from published'; } }), withComments: trait({ afterCreate() { return 'from withComments'; } }), otherTrait: trait({}), afterCreate() { return 'from base'; } }); assert.equal(PostFactory.extractAfterCreateCallbacks({ traits: [] }).length, 1); assert.deepEqual( PostFactory.extractAfterCreateCallbacks({ traits: [] }).map((cb) => cb()), ['from base'] ); assert.equal(PostFactory.extractAfterCreateCallbacks({ traits: ['withComments'] }).length, 2); assert.deepEqual( PostFactory.extractAfterCreateCallbacks({ traits: ['withComments'] }).map((cb) => cb()), ['from base', 'from withComments'] ); assert.equal(PostFactory.extractAfterCreateCallbacks({ traits: ['withComments', 'published'] }).length, 3); assert.deepEqual( PostFactory.extractAfterCreateCallbacks({ traits: ['withComments', 'published'] }).map((cb) => cb()), ['from base', 'from withComments', 'from published'] ); assert.equal(PostFactory.extractAfterCreateCallbacks({ traits: ['withComments', 'otherTrait'] }).length, 2); assert.deepEqual( PostFactory.extractAfterCreateCallbacks({ traits: ['withComments', 'otherTrait'] }).map((cb) => cb()), ['from base', 'from withComments'] ); }); test('isTrait returns true if there is a trait with given name', function(assert) { let PostFactory = Factory.extend({ title: 'Lorem ipsum', published: trait({ isPublished: true }), someNestedObject: { value: 'nested' } }); assert.ok(!PostFactory.isTrait('title')); assert.ok(PostFactory.isTrait('published')); assert.ok(!PostFactory.isTrait('someNestedObject')); assert.ok(!PostFactory.isTrait('notdefined')); });