text: /*jshint expr: true*/
  
  var test = require('tape');
  var State = require('../ampersand-state');
  
  var Person = State.extend({
      props: {
          name: 'string'
      }
  });
  
  test('init with nothing should be okay', function (t) {
      var EmptyModel = State.extend();
      var something = new EmptyModel();
      something.foo = 'bar';
      t.ok(something);
      t.equal(something.foo, 'bar');
      t.end();
  });
  
  test('init with values', function (t) {
      var person = new Person({name: 'henrik'});
      t.ok(person);
      t.equal(person.name, 'henrik');
      t.end();
  });
  
  test('after initialized change should be empty until a set op', function (t) {
      var person = new Person({name: 'phil'});
      t.deepEqual(person._changed, {});
      t.notOk(person.changedAttributes());
      t.end();
  });
  
  test('extended object maintains existing props', function (t) {
      var AwesomePerson = Person.extend({
          props: {
              awesomeness: 'number'
          }
      });
  
      var awesome = new AwesomePerson({
          name: 'Captain Awesome',
          awesomeness: 11
      });
  
      t.equals(awesome.name, 'Captain Awesome');
      t.equals(awesome.awesomeness, 11);
      t.end();
  });
  
  test('extended object maintains existing methods', function (t) {
      var NewPerson = State.extend({
          props: {
              awesomeness: 'number'
          },
          isTrulyAwesome: function () {
              if (this.awesomeness > 10) return true;
          }
      });
      var AwesomePerson = NewPerson.extend({});
      var awesome = new AwesomePerson({
          awesomeness: 11
      });
      t.ok(awesome.isTrulyAwesome());
      t.end();
  });
  
  test('cached derived properties are calculated once per change', function (t) {
      var count = 0;
      var NewPerson = Person.extend({
          derived: {
              greeting: {
                  deps: ['name'],
                  fn: function () {
                      count++;
                      return 'hi, ' + this.name + '!';
                  }
              }
          }
      });
      var person = new NewPerson({name: 'henrik'});
      t.equal(person.greeting, 'hi, henrik!');
  
      // use again, should not increment counter
      person.greeting;
      t.equal(count, 1);
  
      person.name = 'something';
      t.equal(person.greeting, 'hi, something!');
      // reference again
      person.greeting;
      t.equal(count, 2);
  
      t.end();
  });
  
  test('cached derived properties fire events on dependency change', function (t) {
      var NewPerson = Person.extend({
          derived: {
              greeting: {
                  deps: ['name'],
                  fn: function () {
                      return 'hi, ' + this.name + '!';
                  }
              }
          }
      });
      var person = new NewPerson({name: 'henrik'});
      person.on('change:greeting', function (model, value) {
          t.equal(value, 'hi, something!', "shouldn't fire if value is unchanged same value");
          t.end();
      });
      person.name = 'something';
  });
  
  test('cached derived properties fire events if result is different', function (t) {
      t.plan(1);
      var NewPerson = Person.extend({
          derived: {
              greeting: {
                  deps: ['name'],
                  fn: function () {
                      return 'hi, ' + this.name + '!';
                  }
              }
          }
      });
      var person = new NewPerson({name: 'henrik'});
      person.on('change:greeting', function (model, value) {
          t.ok(false, "shouldn't fire if value if derived value is unchanged");
      });
      person.name = 'henrik';
      t.equal(person.name, 'henrik');
      t.end();
  });
  
  test('uncached derived properties always fire events on dependency change', function (t) {
      t.plan(1);
      var NewPerson = Person.extend({
          derived: {
              greeting: {
                  deps: ['name'],
                  cache: false,
                  fn: function () {
                      return 'hello!';
                  }
              }
          }
      });
      var person = new NewPerson({name: 'henrik'});
      person.on('change:greeting', function (model, value) {
          t.equal(value, 'hello!', "Fires despite being same value");
          t.end();
      });
      person.name = 'different';
  });
  
  test('everything should work with a property called `type`. Issue #6.', function (t) {
      var Model = State.extend({
          props: {
              id: 'string',
              type: 'string'
          }
      });
      var model = new Model({id: '50', type: 'hello'});
      t.equal(model.type, 'hello');
      model.type = 'wat?';
      t.equal(model.type, 'wat?');
      t.end();
  });
  
  test('should have cid', function (t) {
      var Model = State.extend({
          props: {
              id: 'string',
              type: 'string'
          }
      });
      var m = new Model();
      t.ok(m.cid);
      t.end();
  });
  
  test('instanceof checks should pass for all parents in the chain', function (t) {
      var P1 = Person.extend({});
      var P2 = P1.extend({});
      var P3 = P2.extend({});
      var p1 = new P1();
      var p2 = new P2();
      var p3 = new P3();
      t.ok(p1 instanceof Person);
      t.ok(p2 instanceof Person);
      t.ok(p3 instanceof Person);
      t.notOk(p1 instanceof P2);
      t.ok(p2 instanceof P2);
      t.ok(p3 instanceof P2);
      t.notOk(p2 instanceof P3);
      t.ok(p3 instanceof P3);
  
      // all of them should have the isState flag too
      t.ok(p1.isState);
      t.ok(p2.isState);
      t.ok(p3.isState);
  
      // shouldn't be possible to change
      p1.isState = false;
      p2.isState = false;
      p3.isState = false;
      t.ok(p1.isState);
      t.ok(p2.isState);
      t.ok(p3.isState);
  
      t.end();
  });
  
  test('custom id and namespace attributes', function (t) {
      var NewPerson = State.extend({
          props: {
              name: 'string',
              _id: 'number',
              ns: 'string'
          },
          idAttribute: '_id',
          namespaceAttribute: 'ns'
      });
      var person = new NewPerson({name: 'henrik', ns: 'group1', _id: 47});
      t.equal(person.getId(), 47);
      t.equal(person.getNamespace(), 'group1');
      t.end();
  });
  
  test('customizable `type` attribute', function (t) {
      var FirstModel = State.extend({
          type: 'hello',
          typeAttribute: 'type'
      });
      var SecondModel = State.extend({
          modelType: 'second'
      });
      var first = new FirstModel();
      var second = new SecondModel();
      t.equal(first.getType(), 'hello');
      t.equal(second.getType(), 'second');
      t.end();
  });
  
  test('constructor should be defined', function (t) {
      var Foo = State.extend({
          props: { name: 'string' }
      });
      var foo = new Foo();
  
      t.ok(foo.constructor);
      t.end();
  });
  
  test('isValid is a thing', function (t) {
      var Foo = State.extend({
          props: { name: ['string', true] },
          validate: function (attrs) {
              if (attrs.name.length < 2) {
                  return "can't be too short";
              }
          }
      });
  
      var foo = new Foo();
      t.notOk(foo.isValid());
      foo.name = 'thing';
      t.ok(foo.isValid());
      t.end();
  });
  
  test("isNew", function (t) {
      var Foo = State.extend({
          props: {
              id: 'number',
              foo: 'number',
              bar: 'number',
              baz: 'number'
          }
      });
      var a = new Foo({ 'foo': 1, 'bar': 2, 'baz': 3});
      t.ok(a.isNew(), "it should be new");
      a = new Foo({ 'foo': 1, 'bar': 2, 'baz': 3, 'id': -5 });
      t.ok(!a.isNew(), "any defined ID is legal, negative or positive");
      a = new Foo({ 'foo': 1, 'bar': 2, 'baz': 3, 'id': 0 });
      t.ok(!a.isNew(), "any defined ID is legal, including zero");
      t.ok(new Foo({}).isNew(), "is true when there is no id");
      t.ok(!new Foo({'id': 2}).isNew(), "is false for a positive integer");
      t.ok(!new Foo({'id': -5}).isNew(), "is false for a negative integer");
      t.end();
  });
  
  test("escape", function (t) {
      var Doc = State.extend({
          props: {
              id: 'string',
              title: 'string',
              author: 'string',
              length: 'number',
              audience: 'string'
          }
      });
      var doc = new Doc({
          id: '1-the-tempest',
          title: "The Tempest",
          author: "Bill Shakespeare",
          length: 123
      });
  
      t.equal(doc.escape('title'), 'The Tempest');
      doc.set({audience: 'Bill & Bob'});
      t.equal(doc.escape('audience'), 'Bill &amp; Bob');
      doc.set({audience: 'Tim > Joan'});
      t.equal(doc.escape('audience'), 'Tim &gt; Joan');
      doc.unset('audience');
      t.equal(doc.escape('audience'), '');
      t.end();
  });
  
  test("set an empty string", function (t) {
      var Model = State.extend({
          props: {
              name: 'string'
          }
      });
      var model = new Model({name : "Model"});
      model.set({name : ''});
      t.equal(model.get('name'), '');
      t.end();
  });
  
  test("setting an object", function (t) {
      var Model = State.extend({
          props: {
              custom: 'object'
          }
      });
      var model = new Model({
          custom: {foo: 1}
      });
      model.on('change', function () {
          t.equal(model.custom.foo, 2);
          t.end();
      });
      model.set({
          custom: {foo: 1} // no change should be fired
      });
      model.set({
          custom: {foo: 2} // change event should be fired
      });
  });
  
  test("clear", function (t) {
      var Model = State.extend({
          props: {
              name: 'string',
              id: 'number',
              length: 'number'
          }
      });
      var changed;
      var model = new Model({id: 1, name : "Model", length: 1});
      model.on("change:name", function () { changed = true; });
      model.clear();
      t.equal(changed, true);
      t.equal(model.get('name'), undefined);
      t.end();
  });
  
  test("changedAttributes", function (t) {
      var Model = State.extend({
          props: {
              a: 'string',
              b: 'string'
          }
      });
      var model = new Model({a: 'a', b: 'b'});
      t.deepEqual(model.changedAttributes(), false);
      t.equal(model.changedAttributes({a: 'a'}), false);
      t.equal(model.changedAttributes({a: 'b'}).a, 'b');
      t.end();
  });
  
  test("change with options", function (t) {
      var value;
      var Model = State.extend({
          props: {
              name: 'string'
          }
      });
      var model = new Model({name: 'Rob'});
      model.on('change', function (model, options) {
          value = options.prefix + model.get('name');
      });
      model.set({name: 'Bob'}, {prefix: 'Mr. '});
      t.equal(value, 'Mr. Bob');
      model.set({name: 'Sue'}, {prefix: 'Ms. '});
      t.equal(value, 'Ms. Sue');
      t.end();
  });
  
  test("change after initialize", function (t) {
      var changed = 0;
      var Model = State.extend({
          props: {
              id: 'number',
              label: 'string'
          }
      });
      var attrs = {id: 1, label: 'c'};
      var obj = new Model(attrs);
      obj.on('change', function () { changed += 1; });
      obj.set(attrs);
      t.equal(changed, 0);
      t.end();
  });
  
  
  test("set triggers changes in the correct order", function (t) {
      var value = null;
      var M = State.extend({});
      var model = new M();
      model.on('last', function () { value = 'last'; });
      model.on('first', function () { value = 'first'; });
      model.trigger('first');
      model.trigger('last');
      t.equal(value, 'last');
      t.end();
  });
  
  test("multiple unsets", function (t) {
      var i = 0;
      var counter = function () { i++; };
      var Model = State.extend({
          props: {
              a: 'string'
          }
      });
      var model = new Model({a: 'a'});
      model.on("change:a", counter);
      model.set({a: 'b'});
      model.unset('a');
      model.unset('a');
      t.equal(i, 2, 'Unset does not fire an event for missing attributes.');
      t.end();
  });
  
  
  test("unset and changedAttributes", function (t) {
      var Model = State.extend({
          props: {
              a: 'number'
          }
      });
      var model = new Model({a: 1});
      model.on('change', function () {
          t.ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');
          t.end();
      });
      model.unset('a');
  });
  
  
  test("change, hasChanged, changedAttributes, previous, previousAttributes", function (t) {
      var Model = State.extend({
          props: {
              name: 'string',
              age: 'number'
          }
      });
      var model = new Model({name: "Tim", age: 10});
      t.deepEqual(model.changedAttributes(), false);
      model.on('change', function () {
          t.ok(model.hasChanged('name'), 'name changed');
          t.ok(!model.hasChanged('age'), 'age did not');
          t.deepEqual(model.changedAttributes(), {name : 'Rob'}, 'changedAttributes returns the changed attrs');
          t.equal(model.previous('name'), 'Tim');
          t.deepEqual(model.previousAttributes(), {name : "Tim", age : 10}, 'previousAttributes is correct');
          t.end();
      });
      t.equal(model.hasChanged(), false);
      t.equal(model.hasChanged(undefined), false);
      model.set({name : 'Rob'});
      t.equal(model.get('name'), 'Rob');
  });
  
  test("validate on unset and clear", function (t) {
      var error;
      var Model = State.extend({
          props: {
              name: 'string'
          }
      });
      var model = new Model({name: "One"});
      model.validate = function (attrs) {
          if (!attrs.name) {
              error = true;
              return "No thanks.";
          }
      };
      model.set({name: "Two"});
      t.equal(model.get('name'), 'Two');
      t.equal(error, undefined);
      model.unset('name', {validate: true});
      t.equal(error, true);
      t.equal(model.get('name'), 'Two');
      model.clear({validate: true});
      t.equal(model.get('name'), 'Two');
      delete model.validate;
      model.clear();
      t.equal(model.get('name'), undefined);
      t.end();
  });
  
  
  test("validate with error callback", function (t) {
      var lastError, boundError;
      var Model = State.extend({
          props: {
              a: 'number',
              admin: 'boolean'
          }
      });
      var model = new Model();
      model.validate = function (attrs) {
          if (attrs.admin) return "Can't change admin status.";
      };
      model.on('invalid', function (model, error) {
          boundError = true;
      });
      var result = model.set({a: 100}, {validate: true});
      t.equal(result, model);
      t.equal(model.get('a'), 100);
      t.equal(model.validationError, null);
      t.equal(boundError, undefined);
      result = model.set({a: 200, admin: true}, {validate: true});
      t.equal(result, false);
      t.equal(model.get('a'), 100);
      t.equal(model.validationError, "Can't change admin status.");
      t.equal(boundError, true);
      t.end();
  });
  
  test("Nested change events don't clobber previous attributes", function (t) {
      new (State.extend({props: {state: 'string', other: 'string'}}))()
          .on('change:state', function (model, newState) {
              t.equal(model.previous('state'), undefined);
              t.equal(newState, 'hello');
              // Fire a nested change event.
              model.set({other: 'whatever'});
          })
          .on('change:state', function (model, newState) {
              t.equal(model.previous('state'), undefined);
              t.equal(newState, 'hello');
              t.end();
          })
          .set({state: 'hello'});
  });
  
  test("hasChanged/set should use same comparison", function (t) {
      var changed = 0;
      var Model = State.extend({
          props: {
              a: 'string'
          }
      });
      var model = new Model({a: 'something'});
      model.on('change', function () {
              t.ok(this.hasChanged('a'));
          })
          .on('change:a', function () {
              changed++;
          })
          .set({a: 'else'});
      t.equal(changed, 1);
      t.end();
  });
  
  
  test("#582, #425, change:attribute callbacks should fire after all changes have occurred", 9, function (t) {
      var Model = State.extend({
          props: {
              a: 'string',
              b: 'string',
              c: 'string'
          }
      });
      var model = new Model();
  
      var assertion = function () {
          t.equal(model.get('a'), 'a');
          t.equal(model.get('b'), 'b');
          t.equal(model.get('c'), 'c');
      };
  
      model.on('change:a', assertion);
      model.on('change:b', assertion);
      model.on('change:c', assertion);
  
      model.set({a: 'a', b: 'b', c: 'c'});
      t.end();
  });
  
  
  test("set same value does not trigger change", function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model({x: 1});
      model.on('change change:x', function () { t.ok(false); });
      model.set({x: 1});
      model.set({x: 1});
      t.end();
  });
  
  test("unset does not fire a change for undefined attributes", 0, function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model({x: undefined});
      model.on('change:x', function () { t.ok(false); });
      model.unset('x');
      t.end();
  });
  
  test("hasChanged works outside of change events, and true within", 6, function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model({x: 1});
      model.on('change:x', function () {
          t.ok(model.hasChanged('x'));
          t.equal(model.get('x'), 1);
      });
      model.set({x: 2}, {silent: true});
      t.ok(model.hasChanged());
      t.equal(model.hasChanged('x'), true);
      model.set({x: 1});
      t.ok(model.hasChanged());
      t.equal(model.hasChanged('x'), true);
      t.end();
  });
  
  test("hasChanged gets cleared on the following set", function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model();
      model.set({x: 1});
      t.ok(model.hasChanged());
      model.set({x: 1});
      t.ok(!model.hasChanged());
      model.set({x: 2});
      t.ok(model.hasChanged());
      model.set({});
      t.ok(!model.hasChanged());
      t.end();
  });
  
  test("`hasChanged` for falsey keys", function (t) {
      var Model = State.extend({
          props: {
              x: 'boolean'
          }
      });
      var model = new Model();
      model.set({x: true}, {silent: true});
      t.ok(!model.hasChanged(0));
      t.ok(!model.hasChanged(''));
      t.end();
  });
  
  test("`previous` for falsey keys", function (t) {
      var Model = State.extend({
          props: {
              0: 'boolean',
              '': 'boolean'
          }
      });
      var model = new Model({0: true, '': true});
      model.set({0: false, '': false}, {silent: true});
      t.equal(model.previous(0), true);
      t.equal(model.previous(''), true);
      t.end();
  });
  
  test("validate", function (t) {
      var lastError;
      var Model = State.extend({
          props: {
              admin: ['boolean', true, true],
              a: 'number'
          }
      });
      var model = new Model();
      model.validate = function (attrs) {
          if (attrs.admin != this.get('admin')) return "Can't change admin status.";
      };
      model.on('invalid', function (model, error) {
          lastError = error;
      });
      var result = model.set({a: 100});
      t.equal(result, model);
      t.equal(model.get('a'), 100);
      t.equal(lastError, undefined);
      result = model.set({admin: true});
      t.equal(model.get('admin'), true);
      result = model.set({a: 200, admin: false}, {validate: true});
      t.equal(lastError, "Can't change admin status.");
      t.equal(result, false);
      t.equal(model.get('a'), 100);
      t.end();
  });
  
  test("set and unset", function (t) {
      var Model = State.extend({
          props: {
              id: 'string',
              foo: 'number',
              bar: 'number',
              baz: 'number',
              extra: 'string'
          }
      });
      var a = new Model({id: 'id', foo: 1, bar: 2, baz: 3});
      var changeCount = 0;
      a.on("change:foo", function () { changeCount += 1; });
      a.set({'foo': 2});
      t.ok(a.get('foo') == 2, "Foo should have changed.");
      t.ok(changeCount == 1, "Change count should have incremented.");
      a.set({'foo': 2}); // set with value that is not new shouldn't fire change event
      t.ok(a.get('foo') == 2, "Foo should NOT have changed, still 2");
      t.ok(changeCount == 1, "Change count should NOT have incremented.");
  
      a.validate = function (attrs) {
          t.equal(attrs.foo, void 0, "validate: true passed while unsetting");
      };
      a.unset('foo', {validate: true});
      t.equal(a.get('foo'), void 0, "Foo should have changed");
      delete a.validate;
      t.ok(changeCount == 2, "Change count should have incremented for unset.");
  
      a.unset('id');
      t.equal(a.id, undefined, "Unsetting the id should remove the id property.");
      t.end();
  });
  
  test("unset even if value has been specified", function (t) {
      var Model = State.extend({
          props: {
              foo: 'string'
          }
      });
      var model = new Model({ foo: 'bar' });
      model.on('change:foo', function () {
          t.equal(model.get('foo'), undefined);
      });
      model.set({ foo: 'baz' }, { unset: true });
      t.equal(model.get('foo'), undefined);
      t.end();
  });
  
  test("nested `set` during `'change:attr'`", function (t) {
      var events = [];
      var Model = State.extend({
          props: {
              x: 'boolean',
              y: 'boolean',
              z: 'boolean'
          }
      });
      var model = new Model();
      model.on('all', function (event) { events.push(event); });
      model.on('change', function () {
          model.set({z: true}, {silent: true});
      });
      model.on('change:x', function () {
          model.set({y: true});
      });
      model.set({x: true});
      t.deepEqual(events, ['change:y', 'change:x', 'change']);
      events = [];
      model.set({z: true});
      t.deepEqual(events, []);
      t.end();
  });
  
  
  
  test("nested `change` only fires once", function (t) {
      t.plan(1);
      var model = new (State.extend({props: {x: 'boolean'}}))();
      model.on('change', function () {
          t.ok(true);
          model.set({x: true});
      });
      model.set({x: true});
  });
  
  test("nested `set` during `'change'`", function (t) {
      var count = 0;
      var Model = State.extend({
          props: {
              x: 'boolean',
              y: 'boolean',
              z: 'boolean'
          }
      });
      var model = new Model();
      model.on('change', function () {
          switch (count++) {
          case 0:
              t.deepEqual(this.changedAttributes(), {x: true});
              t.equal(model.previous('x'), undefined);
              model.set({y: true});
              break;
          case 1:
              t.deepEqual(this.changedAttributes(), {x: true, y: true});
              t.equal(model.previous('x'), undefined);
              model.set({z: true});
              break;
          case 2:
              t.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
              t.equal(model.previous('y'), undefined);
              break;
          default:
              t.ok(false);
          }
      });
      model.set({x: true});
      t.end();
  });
  
  
  test("nested `change` with silent", function (t) {
      var count = 0;
      var Model = State.extend({
          props: {
              x: 'boolean',
              y: 'boolean',
              z: 'boolean'
          }
      });
      var model = new Model();
      model.on('change:y', function () { t.ok(false); });
      model.on('change', function () {
          switch (count++) {
          case 0:
              t.deepEqual(this.changedAttributes(), {x: true});
              model.set({y: true}, {silent: true});
              model.set({z: true});
              break;
          case 1:
              t.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
              break;
          case 2:
              t.deepEqual(this.changedAttributes(), {z: false});
              break;
          default:
              t.ok(false);
          }
      });
      model.set({x: true});
      model.set({z: false});
      t.end();
  });
  
  
  test("nested `change:attr` with silent", function (t) {
      var Model = State.extend({
          props: {
              x: 'boolean',
              y: 'boolean',
              z: 'boolean'
          }
      });
      var model = new Model();
      model.on('change:y', function () { t.ok(false); });
      model.on('change', function () {
          model.set({y: true}, {silent: true});
          model.set({z: true});
      });
      model.set({x: true});
      t.end();
  });
  
  test("multiple nested changes with silent", function (t) {
      var Model = State.extend({
          props: {
              x: 'boolean',
              y: 'number'
          }
      });
      var model = new Model();
      model.on('change:x', function () {
          model.set({y: 1}, {silent: true});
          model.set({y: 2});
      });
      model.on('change:y', function (model, val) {
          t.equal(val, 2);
      });
      model.set({x: true});
      t.end();
  });
  
  
  test("multiple nested changes with silent", function (t) {
      var changes = [];
      var Model = State.extend({
          props: {
              b: 'number'
          }
      });
      var model = new Model();
      model.on('change:b', function (model, val) { changes.push(val); });
      model.on('change', function () {
          model.set({b: 1});
      });
      model.set({b: 0});
      t.deepEqual(changes, [0, 1]);
      t.end();
  });
  
  test("basic silent change semantics", function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model();
      model.set({x: 1});
      model.on('change', function () { t.ok(true); });
      model.set({x: 2}, {silent: true});
      model.set({x: 1});
      t.end();
  });
  
  test("nested set multiple times", function (t) {
      var Model = State.extend({
          props: {
              a: 'boolean',
              b: 'boolean'
          }
      });
      var model = new Model();
      model.on('change:b', function () {
          t.ok(true);
      });
      model.on('change:a', function () {
          model.set({b: true});
          model.set({b: true});
      });
      model.set({a: true});
      t.end();
  });
  
  
  test("#1122 - clear does not alter options.", function (t) {
      var model = new (State.extend({}))();
      var options = {};
      model.clear(options);
      t.ok(!options.unset);
      t.end();
  });
  
  test("#1122 - unset does not alter options.", function (t) {
      var Model = State.extend({
          props: {
              x: 'number'
          }
      });
      var model = new Model();
      var options = {};
      model.unset('x', options);
      t.ok(!options.unset);
      t.end();
  });
  