From c4607fa1312031e84056097fb0138a83db161ae1 Mon Sep 17 00:00:00 2001 From: Stanley Stuart Date: Fri, 22 May 2015 17:13:44 -0500 Subject: [PATCH] deprecate support for DS.FixtureAdapter The FixtureAdapter has needed work for a long time, and without a champion to maintain it, it is being moved out of core and into an addon. You can see the addon at https://github.com/emberjs/ember-data-fixture-adapter/tree/master. We recommend you use an AJAX stubbing solution such as Pretender: https://github.com/trek/pretender --- CHANGELOG.md | 4 + README.md | 6 - packages/ember-data/lib/main.js | 17 +- .../adapter/fixture-adapter-test.js | 347 ------------------ .../integration/record-array-manager-test.js | 2 +- .../relationships/has-many-test.js | 42 ++- .../tests/integration/store-test.js | 6 +- 7 files changed, 54 insertions(+), 370 deletions(-) delete mode 100644 packages/ember-data/tests/integration/adapter/fixture-adapter-test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 5326dff0e39..87ec5f9cf04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Master +- Removed support for DS.FixtureAdapter. You can use it as an addon, or + build it using [Ember Giftwrap](https://github.com/ef4/ember-giftwrap). + https://github.com/emberjs/ember-data-fixture-adapter/tree/master + ### Release 1.0.0-beta.18 (May 18, 2015) - [#3066](https://github.com/emberjs/data/pull/3066) Doc typo: primaryTypeClasss -> primaryTypeClass [@lolmaus](https://github.com/lolmaus) diff --git a/README.md b/README.md index c1786969818..3a849b673a5 100644 --- a/README.md +++ b/README.md @@ -117,12 +117,6 @@ adapter translates that into an XHR request to (for example) By default, Ember Data will use the `RESTAdapter`, which adheres to a set of RESTful JSON conventions. -Ember Data also ships with the `FixtureAdapter`, useful for testing and -prototyping before you have a server, and the `ActiveModelAdapter`, -which is designed to work out-of-the-box with the -[`ActiveModel::Serializers`](https://github.com/rails-api/active_model_serializers) -gem for Rails. - To learn more about adapters, including what conventions the `RESTAdapter` follows and how to build your own, see the Ember.js Guides: [Connecting to an HTTP diff --git a/packages/ember-data/lib/main.js b/packages/ember-data/lib/main.js index f38d926cc85..ee74fb405b2 100644 --- a/packages/ember-data/lib/main.js +++ b/packages/ember-data/lib/main.js @@ -104,7 +104,6 @@ DS.RecordArrayManager = RecordArrayManager; DS.RESTAdapter = RESTAdapter; DS.BuildURLMixin = BuildURLMixin; -DS.FixtureAdapter = FixtureAdapter; DS.RESTSerializer = RESTSerializer; DS.JSONSerializer = JSONSerializer; @@ -135,6 +134,22 @@ Ember.defineProperty(DS, 'normalizeModelName', { value: normalizeModelName }); +var fixtureAdapterWasDeprecated = false; + +Ember.defineProperty(DS, 'FixtureAdapter', { + enumerable: true, + writable: false, + configurable: false, + value: null, + get: function() { + if (!fixtureAdapterWasDeprecated) { + Ember.deprecate('DS.FixtureAdapter has been deprecated and moved into an unsupported addon: https://github.com/emberjs/ember-data-fixture-adapter/tree/master'); + fixtureAdapterWasDeprecated = true + } + return FixtureAdapter; + } +}); + Ember.lookup.DS = DS; export default DS; diff --git a/packages/ember-data/tests/integration/adapter/fixture-adapter-test.js b/packages/ember-data/tests/integration/adapter/fixture-adapter-test.js deleted file mode 100644 index 8bb1f14b5c1..00000000000 --- a/packages/ember-data/tests/integration/adapter/fixture-adapter-test.js +++ /dev/null @@ -1,347 +0,0 @@ -var get = Ember.get; -var env, Person, Phone; -var run = Ember.run; - -module("integration/adapter/fixture_adapter - DS.FixtureAdapter", { - setup: function() { - Person = DS.Model.extend({ - firstName: DS.attr('string'), - lastName: DS.attr('string'), - - height: DS.attr('number'), - - phones: DS.hasMany('phone', { async: true }) - }); - - Phone = DS.Model.extend({ - person: DS.belongsTo('person', { async: true }) - }); - - env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter }); - env.adapter.simulateRemoteResponse = true; - env.adapter.latency = 50; - - // Enable setTimeout. - Ember.testing = false; - - Person.FIXTURES = []; - Phone.FIXTURES = []; - }, - teardown: function() { - Ember.testing = true; - - run(env.container, 'destroy'); - } -}); - -test("should load data for a type asynchronously when it is requested", function() { - Person.FIXTURES = [{ - id: 'wycats', - firstName: "Yehuda", - lastName: "Katz", - - height: 65 - }, - - { - id: 'ebryn', - firstName: "Erik", - lastName: "Brynjolffsosysdfon", - - height: 70, - phones: [1, 2] - }]; - - Phone.FIXTURES = [{ - id: 1, - person: 'ebryn' - }, { - id: 2, - person: 'ebryn' - }]; - - run(env.store, 'find', 'person', 'ebryn').then(async(function(ebryn) { - equal(get(ebryn, 'isLoaded'), true, "data loads asynchronously"); - equal(get(ebryn, 'height'), 70, "data from fixtures is loaded correctly"); - - return Ember.RSVP.hash({ ebryn: ebryn, wycats: env.store.find('person', 'wycats') }); - }, 1000)).then(async(function(records) { - equal(get(records.wycats, 'isLoaded'), true, "subsequent requests for records are returned asynchronously"); - equal(get(records.wycats, 'height'), 65, "subsequent requested records contain correct information"); - - return get(records.ebryn, 'phones'); - }, 1000)).then(async(function(phones) { - equal(get(phones, 'length'), 2, "relationships from fixtures is loaded correctly"); - }, 1000)); -}); - -test("should load data asynchronously at the end of the runloop when simulateRemoteResponse is false", function() { - Person.FIXTURES = [{ - id: 'wycats', - firstName: "Yehuda" - }]; - - env.adapter.simulateRemoteResponse = false; - - var wycats; - - Ember.run(function() { - env.store.find('person', 'wycats').then(function(person) { - wycats = person; - }); - }); - - ok(get(wycats, 'isLoaded'), 'isLoaded is true after runloop finishes'); - equal(get(wycats, 'firstName'), 'Yehuda', 'record properties are defined after runloop finishes'); -}); - -test("should create record asynchronously when it is committed", function() { - var paul; - equal(Person.FIXTURES.length, 0, "Fixtures is empty"); - - run(function() { - paul = env.store.createRecord('person', { firstName: 'Paul', lastName: 'Chavard', height: 70 }); - }); - - paul.on('didCreate', async(function() { - equal(get(paul, 'isNew'), false, "data loads asynchronously"); - equal(get(paul, 'isDirty'), false, "data loads asynchronously"); - equal(get(paul, 'height'), 70, "data from fixtures is saved correctly"); - - equal(Person.FIXTURES.length, 1, "Record added to FIXTURES"); - - var fixture = Person.FIXTURES[0]; - - ok(typeof fixture.id === 'string', "The fixture has an ID generated for it"); - equal(fixture.firstName, 'Paul'); - equal(fixture.lastName, 'Chavard'); - equal(fixture.height, 70); - })); - - paul.save(); -}); - -test("should update record asynchronously when it is committed", function() { - equal(Person.FIXTURES.length, 0, "Fixtures is empty"); - - var paul = env.store.push('person', { id: 1, firstName: 'Paul', lastName: 'Chavard', height: 70 }); - - paul.set('height', 80); - - paul.on('didUpdate', async(function() { - equal(get(paul, 'isDirty'), false, "data loads asynchronously"); - equal(get(paul, 'height'), 80, "data from fixtures is saved correctly"); - - equal(Person.FIXTURES.length, 1, "Record FIXTURES updated"); - - var fixture = Person.FIXTURES[0]; - - equal(fixture.firstName, 'Paul'); - equal(fixture.lastName, 'Chavard'); - equal(fixture.height, 80); - }, 1000)); - - paul.save(); -}); - -test("should delete record asynchronously when it is committed", function() { - stop(); - - var timer = setTimeout(function() { - start(); - ok(false, "timeout exceeded waiting for fixture data"); - }, 1000); - - equal(Person.FIXTURES.length, 0, "Fixtures empty"); - - var paul = env.store.push('person', { id: 'paul', firstName: 'Paul', lastName: 'Chavard', height: 70 }); - - paul.save().then(function() { - paul.deleteRecord(); - paul.save(); - }); - - paul.on('didDelete', function() { - clearTimeout(timer); - start(); - - equal(get(paul, 'isDeleted'), true, "data deleted asynchronously"); - equal(get(paul, 'isDirty'), false, "data deleted asynchronously"); - - equal(Person.FIXTURES.length, 0, "Record removed from FIXTURES"); - }); - -}); - -test("should follow isUpdating semantics", function() { - var timer = setTimeout(function() { - start(); - ok(false, "timeout exceeded waiting for fixture data"); - }, 1000); - - stop(); - - Person.FIXTURES = [{ - id: "twinturbo", - firstName: "Adam", - lastName: "Hawkins", - height: 65 - }]; - - var result = env.store.findAll('person'); - - result.then(function(all) { - clearTimeout(timer); - start(); - equal(get(all, 'isUpdating'), false, "isUpdating is set when it shouldn't be"); - }); -}); - -test("should coerce integer ids into string", function() { - Person.FIXTURES = [{ - id: 1, - firstName: "Adam", - lastName: "Hawkins", - height: 65 - }]; - - env.store.find('person', 1).then(async(function(result) { - strictEqual(get(result, 'id'), "1", "should load integer model id as string"); - })); -}); - -test("should coerce belongsTo ids into string", function() { - Person.FIXTURES = [{ - id: 1, - firstName: "Adam", - lastName: "Hawkins", - - phones: [1] - }]; - - Phone.FIXTURES = [{ - id: 1, - person: 1 - }]; - - env.store.find('phone', 1).then(async(function(result) { - get(result, 'person').then(async(function(person) { - strictEqual(get(person, 'id'), "1", "should load integer belongsTo id as string"); - strictEqual(get(person, 'firstName'), "Adam", "resolved relationship with an integer belongsTo id"); - })); - })); -}); - -test("only coerce belongsTo ids to string if id is defined and not null", function() { - Person.FIXTURES = []; - - Phone.FIXTURES = [{ - id: 1 - }]; - - env.store.find('phone', 1).then(async(function(phone) { - phone.get('person').then(async(function(person) { - equal(person, null); - })); - })); -}); - -test("should throw if ids are not defined in the FIXTURES", function() { - Person.FIXTURES = [{ - firstName: "Adam", - lastName: "Hawkins", - height: 65 - }]; - - raises(function() { - run(function() { - env.store.find('person', 1); - }); - }, /the id property must be defined as a number or string for fixture/); -}); - -test("0 is an acceptable ID in FIXTURES", function() { - Person.FIXTURES = [{ - id: 0 - }]; - - env.store.find('person', 0).then(async(function() { - ok(true, "0 is an acceptable ID, so no exception was thrown"); - }), function() { - ok(false, "should not get here"); - }); -}); - -asyncTest("copies fixtures instead of passing the direct reference", function() { - var returnedFixture; - - expect(2); - - Person.FIXTURES = [{ - id: '1', - firstName: 'Katie', - lastName: 'Gengler' - }]; - - var PersonAdapter = DS.FixtureAdapter.extend({ - find: function(store, type, id, snapshot) { - return this._super(store, type, id).then(function(fixture) { - return returnedFixture = fixture; - }); - } - }); - - Ember.run(function() { - env.registry.register('adapter:person', PersonAdapter); - }); - - env.store.find('person', 1).then(function() { - start(); - ok(Person.FIXTURES[0] !== returnedFixture, 'returnedFixture does not have object identity with defined fixture'); - deepEqual(Person.FIXTURES[0], returnedFixture); - }, function(err) { - ok(false, 'got error' + err); - }); -}); - -test("should save hasMany records", function() { - var createPhone, savePerson, assertPersonPhones; - - expect(3); - - Person.FIXTURES = [{ id: 'tomjerry', firstName: "Tom", lastName: "Jerry", height: 3 }]; - - createPhone = async(function(tom) { - env.store.createRecord('phone', { person: tom }); - - return tom.get('phones').then(async(function(p) { - equal(p.get('length'), 1, "hasMany relationships are created in the store"); - return tom; - })); - }); - - savePerson = async(function(tom) { - return tom.save(); - }); - - assertPersonPhones = async(function(record) { - var phonesPromise = record.get('phones'); - - return phonesPromise.then(async(function(phones) { - equal(phones.get('length'), 1, "hasMany relationship saved correctly"); - })); - }); - - var ensureFixtureAdapterDoesNotLeak = async(function() { - env.store.destroy(); - env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter }); - return env.store.find('phone').then(async(function(phones) { - equal(phones.get('length'), 0, "the fixture adapter should not leak after destroying the store"); - })); - }); - env.store.find('person', 'tomjerry').then(createPhone) - .then(savePerson) - .then(assertPersonPhones) - .then(ensureFixtureAdapterDoesNotLeak); - -}); diff --git a/packages/ember-data/tests/integration/record-array-manager-test.js b/packages/ember-data/tests/integration/record-array-manager-test.js index b58f002f78a..fbef834d1b8 100644 --- a/packages/ember-data/tests/integration/record-array-manager-test.js +++ b/packages/ember-data/tests/integration/record-array-manager-test.js @@ -21,7 +21,7 @@ var manager; module("integration/record_array_manager- destroy", { setup: function() { env = setupStore({ - adapter: DS.FixtureAdapter.extend() + adapter: DS.RESTAdapter.extend() }); store = env.store; diff --git a/packages/ember-data/tests/integration/relationships/has-many-test.js b/packages/ember-data/tests/integration/relationships/has-many-test.js index 791554f3765..ad4981cfa39 100644 --- a/packages/ember-data/tests/integration/relationships/has-many-test.js +++ b/packages/ember-data/tests/integration/relationships/has-many-test.js @@ -1268,24 +1268,42 @@ test("adding and removing records from hasMany relationship #2666", function() { var Post = DS.Model.extend({ comments: DS.hasMany('comment', { async: true }) }); - Post.reopenClass({ - FIXTURES: [ - { id: 1, comments: [1, 2, 3] } - ] - }); + var POST_FIXTURES = [ + { id: 1, comments: [1, 2, 3] } + ]; var Comment = DS.Model.extend({ post: DS.belongsTo('post') }); - Comment.reopenClass({ - FIXTURES: [ - { id: 1 }, - { id: 2 }, - { id: 3 } - ] + + var COMMENT_FIXTURES = [ + { id: 1 }, + { id: 2 }, + { id: 3 } + ]; + + env = setupStore({ + post: Post, + comment: Comment, + adapter: DS.RESTAdapter }); - env = setupStore({ post: Post, comment: Comment, adapter: DS.FixtureAdapter }); + env.registry.register('adapter:comment', DS.RESTAdapter.extend({ + deleteRecord: function(record) { + return Ember.RSVP.resolve(); + }, + updateRecord: function(record) { + return Ember.RSVP.resolve(); + }, + createRecord: function() { + return Ember.RSVP.resolve(); + } + })); + + run(function() { + env.store.pushMany('post', POST_FIXTURES); + env.store.pushMany('comment', COMMENT_FIXTURES); + }); run(function() { stop(); diff --git a/packages/ember-data/tests/integration/store-test.js b/packages/ember-data/tests/integration/store-test.js index 864c464c9b8..01193671f40 100644 --- a/packages/ember-data/tests/integration/store-test.js +++ b/packages/ember-data/tests/integration/store-test.js @@ -29,7 +29,7 @@ function initializeStore(adapter) { module("integration/store - destroy", { setup: function() { - initializeStore(DS.FixtureAdapter.extend()); + initializeStore(DS.Adapter.extend()); } }); @@ -53,7 +53,7 @@ function tap(obj, methodName, callback) { asyncTest("destroying record during find doesn't cause error", function() { expect(0); - var TestAdapter = DS.FixtureAdapter.extend({ + var TestAdapter = DS.Adapter.extend({ find: function(store, type, id, snapshot) { return new Ember.RSVP.Promise(function(resolve, reject) { Ember.run.next(function() { @@ -81,7 +81,7 @@ asyncTest("destroying record during find doesn't cause error", function() { asyncTest("find calls do not resolve when the store is destroyed", function() { expect(0); - var TestAdapter = DS.FixtureAdapter.extend({ + var TestAdapter = DS.Adapter.extend({ find: function(store, type, id, snapshot) { store.destroy(); Ember.RSVP.resolve(null);