diff --git a/addon/index.js b/addon/index.js index f7921bb1..a1443ea2 100644 --- a/addon/index.js +++ b/addon/index.js @@ -6,7 +6,7 @@ import isEmptyObject from 'ember-changeset/utils/computed/is-empty-object'; import inflate from 'ember-changeset/utils/computed/inflate'; import transform from 'ember-changeset/utils/computed/transform'; import isPromise from 'ember-changeset/utils/is-promise'; -import isObject from 'ember-changeset/utils/is-object'; +import isObject, { isAnyObject } from 'ember-changeset/utils/is-object'; import pureAssign from 'ember-changeset/utils/assign'; import includes from 'ember-changeset/utils/includes'; import take from 'ember-changeset/utils/take'; @@ -287,7 +287,7 @@ export function changeset( let changes /*: { [string]: mixed } */ = get(this, '_bareChanges'); let preparedChanges = prepareChangesFn(changes); - assert('Callback to `changeset.prepare` must return an object', isObject(preparedChanges)); + assert('Callback to `changeset.prepare` must return an object', isAnyObject(preparedChanges)); validateNestedObj('preparedChanges', preparedChanges); let newChanges /*: Changes */ = keys(preparedChanges).reduce((newObj, key) => { @@ -490,7 +490,7 @@ export function changeset( ) /*: T */ { // Construct new `Err` instance. let newError /*: Err */; - if (isObject(error)) { + if (isAnyObject(error)) { let errorLike /*: ErrLike<*> */ = (error /*: any */); assert('Error must have value.', errorLike.hasOwnProperty('value')); assert('Error must have validation.', errorLike.hasOwnProperty('validation')); @@ -709,7 +709,7 @@ export function changeset( setNestedProperty(changes, key, new Change(value)); // ensure cache key is updated with new relay if value is object - if (isObject(value)) { + if (isAnyObject(value)) { let cache /*: RelayCache */ = get(this, RELAY_CACHE); cache[key] = Relay.create({ key, changeset: this, content: value }); } diff --git a/addon/utils/computed/inflate.js b/addon/utils/computed/inflate.js index 4496f992..760a9aff 100644 --- a/addon/utils/computed/inflate.js +++ b/addon/utils/computed/inflate.js @@ -3,7 +3,7 @@ import { computed, get } from '@ember/object'; import deepSet from 'ember-deep-set'; import { assert, runInDebug } from '@ember/debug'; -import isObject from 'ember-changeset/utils/is-object'; +import { isAnyObject } from 'ember-changeset/utils/is-object'; import { isBlank } from '@ember/utils'; const { keys } = Object; @@ -25,7 +25,7 @@ export default function inflate /*:: */ ( if (i < allParts.length - 1) { let path = allParts.slice(0, i+1).join('.'); let msg = `Path ${path} leading up to ${key} must be an Object if specified.`; - assert(msg, isObject(obj[path]) || isBlank(obj[path])); + assert(msg, isAnyObject(obj[path]) || isBlank(obj[path])); } }); }); diff --git a/addon/utils/is-object.js b/addon/utils/is-object.js index 20506500..55e9e505 100644 --- a/addon/utils/is-object.js +++ b/addon/utils/is-object.js @@ -3,5 +3,12 @@ import { typeOf } from '@ember/utils'; export default function isObject(val /*: mixed */) { + if (val) { + return typeOf(val) === 'instance' || Object.getPrototypeOf(val) === Object.prototype; + } + return false; +} + +export function isAnyObject(val /*: mixed */) { return typeOf(val) === 'object' || typeOf(val) === 'instance'; } diff --git a/addon/utils/is-promise.js b/addon/utils/is-promise.js index e42bae83..d29c6d2a 100644 --- a/addon/utils/is-promise.js +++ b/addon/utils/is-promise.js @@ -1,7 +1,7 @@ // @flow import { typeOf } from '@ember/utils'; -import isObject from './is-object'; +import { isAnyObject } from './is-object'; function isPromiseLike(obj /*: mixed */) /*: boolean */ { return !!obj @@ -14,5 +14,5 @@ function isPromiseLike(obj /*: mixed */) /*: boolean */ { } export default function isPromise(obj /*: mixed */) /*: boolean */ { - return isObject(obj) && isPromiseLike(obj); + return isAnyObject(obj) && isPromiseLike(obj); } diff --git a/tests/unit/changeset-test.js b/tests/unit/changeset-test.js index 9f73485c..69508697 100644 --- a/tests/unit/changeset-test.js +++ b/tests/unit/changeset-test.js @@ -199,7 +199,7 @@ module('Unit | Utility | changeset', function(hooks) { assert.equal(result, 'Jim Bob', 'should proxy to content'); }); - test('scott #get returns the content when the proxied content is an object', function(assert) { + test('#get returns the content when the proxied content is an object', function(assert) { class Moment { constructor(date) { this.date = date; @@ -219,8 +219,8 @@ module('Unit | Utility | changeset', function(hooks) { newValue = get(c, 'startDate'); assert.deepEqual(newValue, momentInstance, 'correct getter'); - // assert.ok(newValue instanceof Moment, 'correct instance'); - // assert.equal(newValue.date, d, 'correct date on moment object'); + assert.ok(newValue instanceof Moment, 'correct instance'); + assert.equal(newValue.date, d, 'correct date on moment object'); }); test('#get returns change if present', function(assert) { @@ -321,12 +321,12 @@ module('Unit | Utility | changeset', function(hooks) { let c = new Changeset(model); let actual = get(c, 'foo.bar.dog'); let expectedResult = get(model, 'foo.bar.dog'); - assert.notEqual(actual, expectedResult, "using Ember.get won't work"); + assert.equal(actual, expectedResult, "using Ember.get will work"); } { let c = new Changeset(model); - let actual = get(c, 'foo.bar.dog.content'); + let actual = get(c, 'foo.bar.dog'); let expectedResult = get(model, 'foo.bar.dog'); assert.equal(actual, expectedResult, "you have to use .content"); } diff --git a/tests/unit/utils/is-promise-test.js b/tests/unit/utils/is-promise-test.js index 0259ccfd..a56cfe8e 100644 --- a/tests/unit/utils/is-promise-test.js +++ b/tests/unit/utils/is-promise-test.js @@ -43,6 +43,6 @@ testData.forEach(({ value, expected }) => { test('it checks if an object is an instance of an RSVP.Promise', function(assert) { let result = isPromise(value); - assert.equal(result, expected, `should be ${expected}`); + assert.equal(result, expected, `should be ${expected} for ${value}`); }); });