aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js')
-rw-r--r--tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js335
1 files changed, 335 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js b/tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js
new file mode 100644
index 0000000..b775ff4
--- /dev/null
+++ b/tools/addon-sdk-1.7/packages/api-utils/tests/traits/descriptor-tests.js
@@ -0,0 +1,335 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var Trait = require("light-traits").Trait;
+var utils = require("./utils");
+var Data = utils.Data;
+var Method = utils.Method;
+var Accessor = utils.Accessor;
+var Required = utils.Required;
+var Conflict = utils.Conflict;
+
+function method() {}
+
+exports.Assert = require("./assert").Assert
+exports["test simple composition"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: 0, b: 1 }),
+ { c: { value: 2 }, d: { value: method, enumerable: true } }
+ );
+
+ var expected = {
+ a: Data(0),
+ b: Data(1),
+ c: Data(2, false, false, false),
+ d: Method(method, true, false, false)
+ };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test composition with conflict"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: 0, b: 1 }),
+ {
+ a: {
+ value: 2,
+ writable: true,
+ configurable: true,
+ enumerable: true
+ },
+ c: {
+ value: method,
+ configurable: true
+ }
+ }
+ );
+
+ var expected = {
+ a: Conflict("a"),
+ b: Data(1),
+ c: Method(method, false, true, false)
+ };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test identical props does not cause conflict"] = function(assert) {
+ var actual = Trait.compose(
+ {
+ a: {
+ value: 0,
+ writable: true,
+ configurable: true,
+ enumerable: true
+ },
+ b: {
+ value: 1
+ }
+ },
+ Trait({
+ a: 0,
+ c: method
+ })
+ );
+
+ var expected = {
+ a: Data(0),
+ b: Data(1, false, false, false),
+ c: Method(method)
+ }
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test composition with identical required props"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: Trait.required, b: 1 }),
+ { a: { required: true }, c: { value: method } }
+ );
+
+ var expected = {
+ a: Required(),
+ b: Data(1),
+ c: Method(method, false, false, false)
+ };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test composition satisfying a required prop"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: Trait.required, b: 1 }),
+ { a: { value: method, enumerable: true } }
+ );
+
+ var expected = {
+ a: Method(method, true, false, false),
+ b: Data(1)
+ };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test compose is neutral wrt conflicts"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: { value: 1 } }, Trait({ a: 2 })),
+ { b: { value: 0, writable: true, configurable: true, enumerable: false } }
+ );
+
+ var expected = { a: Conflict("a"), b: Data(0, false) };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test conflicting prop overrides Trait.required"] = function(assert) {
+ var actual = Trait.compose(
+ Trait.compose(
+ Trait({ a: 1 }),
+ { a: { value: 2 } }
+ ),
+ { a: { value: Trait.required } }
+ );
+
+ var expected = { a: Conflict("a") };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test compose is commutative"] = function(assert) {
+ var actual = Trait.compose(
+ Trait({ a: 0, b: 1 }),
+ { c: { value: 2 }, d: { value: method } }
+ );
+
+ var expected = Trait.compose(
+ { c: { value: 2 }, d: { value: method } },
+ Trait({ a: 0, b: 1 })
+ );
+
+ assert.equalTraits(actual, expected);
+}
+
+exports["test compose is commutative, also for required/conflicting props"] = function(assert) {
+ var actual = Trait.compose(
+ {
+ a: { value: 0 },
+ b: { value: 1 },
+ c: { value: 3 },
+ e: { value: Trait.required }
+ },
+ {
+ c: { value: 2 },
+ d: { get: method }
+ }
+ );
+
+ var expected = Trait.compose(
+ Trait({ c: 3 }),
+ {
+ c: { value: 2 },
+ d: { get: method },
+ a: { value: 0 },
+ b: { value: 1 },
+ e: { value: Trait.required },
+ }
+ );
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test compose is associative"] = function(assert) {
+ var actual = Trait.compose(
+ {
+ a: { value: 0 },
+ b: { value: 1 },
+ c: { value: 3 },
+ d: { value: Trait.required }
+ },
+ Trait.compose(
+ { c: { value: 3 }, d: { value: Trait.required } },
+ { c: { value: 2 }, d: { value: method }, e: { value: "foo" } }
+ )
+ );
+
+ var expected = Trait.compose(
+ Trait.compose(
+ {
+ a: { value: 0 },
+ b: { value: 1 },
+ c: { value: 3 },
+ d: { value: Trait.required }
+ },
+ {
+ c: { value: 3 },
+ d: { value: Trait.required }
+ }
+ ),
+ {
+ c: { value: 2 },
+ d: { value: method },
+ e: { value: "foo" }
+ }
+ );
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test diamond import of same prop do not conflict"] = function(assert) {
+ var actual = Trait.compose(
+ Trait.compose(
+ { b: { value: 2 } },
+ { a: { value: 1, enumerable: true, configurable: true, writable: true } }
+ ),
+ Trait.compose(
+ { c: { value: 3 } },
+ Trait({ a: 1 })
+ ),
+ Trait({ d: 4 })
+ );
+
+ var expected = {
+ a: Data(1),
+ b: Data(2, false, false, false),
+ c: Data(3, false, false, false),
+ d: Data(4)
+ };
+
+ assert.equalTraits(actual, expected);
+};
+
+exports["test create simple"] = function(assert) {
+ var o1 = Trait.compose(
+ Trait({ a: 1 }),
+ {
+ b: {
+ value: function() {
+ return this.a;
+ }
+ }
+ }
+ ).create(Object.prototype);
+
+ assert.equal(Object.getPrototypeOf(o1), Object.prototype, "o1 prototype");
+ assert.equal(1, o1.a, "o1.a");
+ assert.equal(1, o1.b(), "o1.b()");
+ assert.equal(Object.keys(o1).length, 1, "Object.keys(o1).length === 2");
+};
+
+exports["test create with Array.prototype"] = function(assert) {
+ var o2 = Trait.compose({}, {}).create(Array.prototype);
+ assert.equal(Object.getPrototypeOf(o2), Array.prototype, "o2 prototype");
+};
+
+exports["test exception for incomplete required properties"] = function(assert) {
+ assert.throws(function() {
+ Trait({ foo: Trait.required }).create(Object.prototype)
+ }, /Missing required property: `foo`/, "required prop error");
+}
+
+exports["test exception for unresolved conflicts"] = function(assert) {
+ assert.throws(function() {
+ Trait(Trait({ a: 0 }), Trait({ a: 1 })).create({})
+ }, /Remaining conflicting property: `a`/, "conflicting prop error");
+}
+
+exports["test conflicting properties are present"] = function(assert) {
+ var o5 = Object.create(Object.prototype, Trait.compose(
+ { a: { value: 0 } },
+ { a: { value: 1 } }
+ ));
+
+ assert.ok("a" in o5, "conflicting property present");
+ assert.throws(function() {
+ o5.a
+ }, /Remaining conflicting property: `a`/, "conflicting prop access error");
+};
+
+exports["test diamond with conflicts"] = function(assert) {
+ function makeT1(x) {
+ return {
+ m: {
+ value: function() {
+ return x
+ }
+ }
+ };
+ };
+
+ function makeT2(x) {
+ return Trait.compose(
+ Trait({ t2: "foo" }),
+ makeT1(x)
+ );
+ };
+
+ function makeT3(x) {
+ return Trait.compose(
+ {
+ t3: { value: "bar" }
+ },
+ makeT1(x)
+ );
+ };
+
+ var T4 = Trait.compose(makeT2(5), makeT3(5));
+
+ assert.throws(function() {
+ T4.create(Object.prototype);
+ }, /Remaining conflicting property: `m`/, "diamond prop conflict");
+};
+
+exports["test providing requirements through proto"] = function(assert) {
+ var t = Trait.compose(
+ {},
+ { required: { required: true } }
+ ).create({ required: "test" });
+
+ assert.equal(t.required, "test", "property from proto is inherited");
+};
+
+if (module == require.main)
+ require("test").run(exports);