UNPKG

can-observe

Version:

Like can.Map, but without the .attr method.

282 lines (223 loc) 7.55 kB
var QUnit = require("steal-qunit"); var observe = require("can-observe"); var canReflect = require("can-reflect"); var canSymbol = require("can-symbol"); var Observation = require("can-observation"); var makeFunction = require("../src/-make-function"); var makeObject = require("../src/-make-object"); var observableSymbol = canSymbol.for("can.meta"); var computedPropertyDefinitionSymbol = canSymbol.for("can.computedPropertyDefinitions"); var observableStore = require("../src/-observable-store"); var helpers = require("../src/-helpers"); QUnit.module("can-observe with Functions"); QUnit.test("isBuiltInButNotArrayOrPlainObject", function(assert) { // Testing type constructors assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(Function), true, "Function"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(Object), true, "Object"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(Date), true, "Date"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(function() {}), false, "function instance"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject({}), false, "new Object"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject([]), false, "new Array"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(new Date()), true, "new Date"); assert.equal(helpers.isBuiltInButNotArrayOrPlainObject(new RegExp()), true, "new RegExp"); }); QUnit.test("makeFunction basics", function(assert) { assert.expect(3); var OriginalPerson = function(first, last) { this.first = first; this.last = last; this.constructor.count++; }; OriginalPerson.prototype.sayHi = function() { return this.first + this.last; }; var observe = function(obj) { if (canReflect.isPrimitive(obj)) { return obj; } if (observableStore.proxies.has(obj)) { return obj; } if (helpers.isBuiltInButNotArrayOrPlainObject(obj)) { return obj; } var observable; if (obj && typeof obj === "object") { observable = makeObject.observable(obj, { observe: observe }); } else if (typeof obj === "function") { observable = makeFunction.observable(obj, { observe: observe }); } else { return obj; } observableStore.proxies.add(observable); observableStore.proxiedObjects.set(obj, observable); return observable; }; var Person = observe(OriginalPerson); assert.equal(Person.prototype.constructor, Person, "Person is its own constructor"); Person.count = 0; canReflect.onKeyValue(Person, "count", function(newVal) { assert.equal(newVal, 1, "static count"); }); var person = new Person("Justin", "Meyer"); canReflect.onKeyValue(person, "first", function(newVal) { assert.equal(newVal, "Vyacheslav", "first changed"); }); person.first = "Vyacheslav"; }); QUnit.test("makeFunction basics, with property definitions", function(assert) { var observe = function(obj) { if (canReflect.isPrimitive(obj)) { return obj; } if (observableStore.proxies.has(obj)) { return obj; } if (helpers.isBuiltInButNotArrayOrPlainObject(obj)) { return obj; } var observable; if (obj && typeof obj === "object") { observable = makeObject.observable(obj, { observe: observe }); } else if (typeof obj === "function") { observable = makeFunction.observable(obj, { observe: observe }); } else { return obj; } observableStore.proxies.add(observable); observableStore.proxiedObjects.set(obj, observable); return observable; }; var OriginalPerson = function(first, last) { this.first = first; this.last = last; this.constructor.count++; }; OriginalPerson.prototype.sayHi = function() { return this.first + " " + this.last; }; OriginalPerson[computedPropertyDefinitionSymbol] = Object.create(null); OriginalPerson[computedPropertyDefinitionSymbol].countText = function(instance) { return new Observation(function() { return this.count === 1 ? "1 person" : (this.count + " people"); }, instance); }; var Person = observe(OriginalPerson); assert.equal(Person.prototype.constructor, Person, "Person is its own constructor"); Person.count = 0; assert.equal(Person.countText, "0 people", "count is 0"); canReflect.onKeyValue(Person, "countText", function(newVal) { assert.equal(newVal, "1 person", "static count"); }); var person = new Person("Christopher", "Baker"); assert.equal(Person.countText, "1 person", "count is 1"); canReflect.onKeyValue(person, "first", function(newVal) { assert.equal(newVal, "Yetti", "first changed"); }); person.first = "Yetti"; }); QUnit.test("custom, non-array functions return proxied objects as well", function(assert) { var p = observe({ foo: function() { return {}; } }); assert.ok(p.foo()[observableSymbol], "Proxied function returns proxy"); }); QUnit.test("basics with constructor functions", function(assert) { assert.expect(3); var OriginalPerson = function(first, last) { this.first = first; this.last = last; this.constructor.count++; }; OriginalPerson.prototype.sayHi = function() { return this.first + this.last; }; var Person = observe(OriginalPerson); assert.equal(Person.prototype.constructor, Person, "Person is its own constructor"); Person.count = 0; canReflect.onKeyValue(Person, "count", function(newVal) { assert.equal(newVal, 1, "static count"); }); var person = new Person("Justin", "Meyer"); canReflect.onKeyValue(person, "first", function(newVal) { assert.equal(newVal, "Vyacheslav", "first changed"); }); person.first = "Vyacheslav"; }); QUnit.test("Constructor functions that use instanceof", function(assert) { var Child; var Parent = function(){ var isParent = (this instanceof Parent); assert.ok(isParent, "this is a Parent"); var isChild = (this instanceof Child); assert.ok(isChild, "this is a Child"); }; Parent.prototype.fn = function() { return "works"; }; Child = observe(Parent); var child = new Child(); assert.equal(child.fn(), "works", "Able to walk up the prototype"); }); require("can-reflect-tests/observables/map-like/type/type")("simple map-like constructor", function() { return observe(function(props) { canReflect.assign(this, props || {}); }); }); QUnit.test(".constructor of array subclass is itself", function(assert) { var MyArray = function(values) { this.push.apply(this, arguments); }; MyArray.prototype = Object.create(Array.prototype); MyArray.prototype.constructor = MyArray; var ArrayType = observe(MyArray); assert.equal(ArrayType.prototype.constructor, ArrayType, "type"); var arr = new MyArray(); assert.equal(arr.constructor, ArrayType, "instance"); }); var classSupport = (function() { try { eval('"use strict"; class A{};'); return true; } catch (e) { return false; } })(); if (classSupport) { require("can-reflect-tests/observables/list-like/type/on-instance-patches")("class extends Array", function() { class MyArray extends Array { } return observe(MyArray); }); QUnit.test("calling methods (that have no prototypes)", function(assert) { class AddBase { constructor() { this.count = 0; } add(){ this.count++; } } var Add = observe(AddBase); var add = new Add(); add.add(); assert.equal(add.count,1, "count set"); }); } require("can-reflect-tests/observables/list-like/type/on-instance-patches")("Object.create(Array)", function() { var MyArray = function(values) { this.push.apply(this, arguments); }; MyArray.prototype = Object.create(Array.prototype); MyArray.prototype.constructor = MyArray; return observe(MyArray); });