"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var chai = require("chai");
var assert = chai.assert;
var ts = require("../src/typesystem");
var rs = require("../src/restrictions");
var ms = require("../src/metainfo");
var facetRegistry = require("../src/facetRegistry");
var typeExpressions = require("../src/typeExpressions");
var typesystem_1 = require("../src/typesystem");
var restrictions_1 = require("../src/restrictions");
var restrictions_2 = require("../src/restrictions");
var restrictions_3 = require("../src/restrictions");
var restrictions_4 = require("../src/restrictions");
var restrictions_5 = require("../src/restrictions");
var restrictions_6 = require("../src/restrictions");
var restrictions_7 = require("../src/restrictions");
var restrictions_8 = require("../src/restrictions");
var restrictions_9 = require("../src/restrictions");
var restrictions_10 = require("../src/restrictions");
var typesystem_2 = require("../src/typesystem");
var restrictions_11 = require("../src/restrictions");
var restrictions_12 = require("../src/restrictions");
var restrictions_13 = require("../src/restrictions");
var restrictions_14 = require("../src/restrictions");
describe("Built-ins", function () {
    it("built in types exist", function () {
        chai.assert(ts.ARRAY != null);
        chai.assert(ts.ANY.allSubTypes().indexOf(ts.BOOLEAN) != -1);
    });
    it("built in type registry", function () {
        chai.assert(ts.builtInRegistry().get("boolean"));
        chai.assert(!ts.builtInRegistry().get("boo3lean"));
    });
    it("cycles does not cause a problem", function () {
        var p = ts.OBJECT.inherit("Person");
        var friend = p.inherit("Friend");
        p.addSuper(friend);
        chai.assert(p.allSuperTypes().length == 4);
    });
    it("union gather options of other unions", function () {
        var t1 = ts.union("numberOrString", [ts.NUMBER, ts.STRING]);
        var t2 = ts.union("numberOrBoolean", [t1, ts.BOOLEAN]);
        var allopts = t2.allOptions();
        assert.equal(allopts.length, 3);
    });
    it("union gather options of other unions 2", function () {
        var t1 = ts.union("numberOrString", [ts.NUMBER, ts.STRING]);
        var t2 = ts.union("numberOrBoolean", [t1, ts.NUMBER]);
        var allopts = t2.allOptions();
        assert.equal(allopts.length, 2);
    });
    it("union gather options of other unions 2", function () {
        var t1 = ts.intersect("numberOrString", [ts.NUMBER, ts.STRING]);
        var t2 = ts.intersect("numberOrBoolean", [t1, ts.NUMBER]);
        var allopts = t2.allOptions();
        assert.equal(allopts.length, 2);
    });
    it("simple check direct", function () {
        assert.isTrue(!ts.NOTHING.validate(2).isOk());
        assert.isTrue(ts.NOTHING.validate(null).isOk());
    });
    it("hierarchy test", function () {
        var mi = ts.derive("integer", [ts.NUMBER]);
        var mi3 = ts.derive("myinteger", [mi]);
        assert.equal(ts.NUMBER.allSubTypes().length, 1);
        assert.equal(mi.allSubTypes().length, 1);
        assert.equal(mi3.allSuperTypes().length, 4);
    });
    it("number check direct", function () {
        var mi = ts.derive("integer", [ts.NUMBER]);
        var mi3 = ts.derive("myinteger", [mi]);
        assert.isTrue(mi3.validateDirect(4).isOk());
        assert.isTrue(!mi3.validateDirect("d").isOk());
    });
    it("union check direct", function () {
        var mi = ts.union("numberOrString", [ts.NUMBER, ts.STRING]);
        assert.isTrue(mi.validateDirect(4).isOk());
        assert.isTrue(mi.validateDirect("d").isOk());
        assert.isFalse(mi.validateDirect(false).isOk());
    });
    it("intersection check direct", function () {
        var mi = ts.intersect("scalarAndString", [ts.SCALAR, ts.STRING]);
        assert.isTrue(!mi.validateDirect(4).isOk());
        assert.isTrue(mi.validateDirect("d").isOk());
        assert.isFalse(mi.validateDirect(false).isOk());
    });
    it("integer restrictions", function () {
        assert.isTrue(ts.INTEGER.validateDirect(5).isOk());
        assert.isTrue(!ts.INTEGER.validateDirect(5.2).isOk());
        assert.isTrue(!ts.INTEGER.validateDirect("3").isOk());
    });
    it("object restrictions", function () {
        var p = ts.derive("Person", [ts.OBJECT]);
        assert.isTrue(p.validateDirect({}).isOk());
        assert.isTrue(!p.validateDirect([]).isOk());
        assert.isTrue(!p.validateDirect("").isOk());
    });
    it("array restrictions", function () {
        var p = ts.derive("Person", [ts.ARRAY]);
        assert.isTrue(!p.validateDirect({}).isOk());
        assert.isTrue(p.validateDirect([]).isOk());
        assert.isTrue(!p.validateDirect("").isOk());
    });
});
describe("Simple instanceof tests", function () {
    it("declareProperty of correct type", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        var st = person.validateDirect({ name: "Pavel" });
        assert.isTrue(st.isOk());
    });
    it("declareProperty of incorrect type", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        var st = person.validateDirect({ name: 2 });
        assert.isTrue(!st.isOk());
    });
    it("properties can be closed", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel", d: "j3" });
        assert.isTrue(!st.isOk());
    });
    it("properties are closed positive", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel" });
        assert.isTrue(st.isOk());
    });
    it("properties min properties", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.addMeta(new rs.MinProperties(2));
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel" });
        assert.isTrue(!st.isOk());
    });
    it("properties min properties 2", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.addMeta(new rs.MinProperties(2));
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel", age: 2 });
        assert.isTrue(st.isOk());
    });
    it("properties max properties", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.addMeta(new rs.MaxProperties(1));
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel", age: 2 });
        assert.isTrue(!st.isOk());
    });
    it("properties max properties 2", function () {
        var person = ts.deriveObjectType("Person");
        person.declareProperty("name", ts.STRING, false);
        person.declareProperty("age", ts.NUMBER, true);
        person.addMeta(new rs.MaxProperties(2));
        person.closeUnknownProperties();
        var st = person.validateDirect({ name: "Pavel", age: 2 });
        assert.isTrue(st.isOk());
    });
    it("properties max items", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.MaxItems(1));
        var st = person.validateDirect([2, 1]);
        assert.isTrue(!st.isOk());
    });
    it("properties max items 2", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.MaxItems(1));
        var st = person.validateDirect([1]);
        assert.isTrue(st.isOk());
    });
    it("properties min items", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.MinItems(1));
        var st = person.validateDirect([]);
        assert.isTrue(!st.isOk());
    });
    it("properties min items 2", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.MinItems(1));
        var st = person.validateDirect([1]);
        assert.isTrue(st.isOk());
    });
    it("properties min length", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.MinLength(1));
        var st = person.validateDirect("");
        assert.isTrue(!st.isOk());
    });
    it("properties min length 2", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.MinItems(1));
        var st = person.validateDirect("a");
        assert.isTrue(st.isOk());
    });
    it("properties max length", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.MaxLength(1));
        var st = person.validateDirect("");
        assert.isTrue(st.isOk());
    });
    it("properties max length 2", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.MaxLength(1));
        var st = person.validateDirect("aa");
        assert.isTrue(!st.isOk());
    });
    it("properties maximum", function () {
        var person = ts.derive("Person", [ts.NUMBER]);
        person.addMeta(new rs.Maximum(1));
        var st = person.validateDirect(0);
        assert.isTrue(st.isOk());
    });
    it("properties maximum 2", function () {
        var person = ts.derive("Person", [ts.NUMBER]);
        person.addMeta(new rs.Maximum(1));
        var st = person.validateDirect(2);
        assert.isTrue(!st.isOk());
    });
    it("properties minumum", function () {
        var person = ts.derive("Person", [ts.NUMBER]);
        person.addMeta(new rs.Minimum(0));
        var st = person.validateDirect(0);
        assert.isTrue(st.isOk());
    });
    it("properties minumum 2", function () {
        var person = ts.derive("Person", [ts.NUMBER]);
        person.addMeta(new rs.Minimum(4));
        var st = person.validateDirect(2);
        assert.isTrue(!st.isOk());
    });
    it("unique items", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.UniqueItems(true));
        var st = person.validateDirect([2, 2]);
        assert.isTrue(!st.isOk());
    });
    it("unique items 2", function () {
        var person = ts.derive("Person", [ts.ARRAY]);
        person.addMeta(new rs.UniqueItems(false));
        var st = person.validateDirect([2, 3]);
        assert.isTrue(st.isOk());
    });
    it("pattern", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.Pattern("^.$"));
        var st = person.validateDirect("a");
        assert.isTrue(st.isOk());
    });
    it("pattern 2", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.addMeta(new rs.Pattern("^.$"));
        var st = person.validateDirect("as");
        assert.isTrue(!st.isOk());
    });
    it("map property", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.declareProperty("name", ts.STRING, false);
        person.declareMapProperty(".", ts.NUMBER);
        var st = person.validateDirect({ name: "Pavel", d: "dd" });
        assert.isTrue(!st.isOk());
    });
    it("map property 2", function () {
        var person = ts.derive("Person", [ts.STRING]);
        person.declareProperty("name", ts.STRING, true);
        person.declareMapProperty(".", ts.NUMBER);
        var st = person.validateDirect({ d: 4 });
        assert.isTrue(!st.isOk());
    });
    it("component should be of type", function () {
        var arr = ts.derive("ints", [ts.ARRAY]);
        arr.addMeta(new rs.ComponentShouldBeOfType(ts.NUMBER));
        var s = arr.validateDirect([3, 4]);
        assert.isTrue(s.isOk());
    });
    it("component should be of type 2", function () {
        var arr = ts.derive("ints", [ts.ARRAY]);
        arr.addMeta(new rs.ComponentShouldBeOfType(ts.NUMBER));
        var s = arr.validateDirect([3, "DD"]);
        assert.isTrue(!s.isOk());
    });
    it("enum", function () {
        var arr = ts.derive("ints", [ts.STRING]);
        arr.addMeta(new rs.Enum(["a", "b"]));
        var s = arr.validateDirect("c");
        assert.isTrue(!s.isOk());
    });
    it("enum 2", function () {
        var arr = ts.derive("ints", [ts.STRING]);
        arr.addMeta(new rs.Enum(["a", "b"]));
        var s = arr.validateDirect("a");
        assert.isTrue(s.isOk());
    });
    it("additional property", function () {
        var arr = ts.derive("ints", [ts.OBJECT]);
        arr.addMeta(new rs.AdditionalPropertyIs(ts.INTEGER));
        var s = arr.validateDirect({ z: 2 });
        assert.isTrue(s.isOk());
    });
    it("additional property 2", function () {
        var arr = ts.derive("ints", [ts.OBJECT]);
        arr.addMeta(new rs.AdditionalPropertyIs(ts.INTEGER));
        var s = arr.validateDirect({ z: "V" });
        assert.isTrue(!s.isOk());
    });
    it("additional property 3", function () {
        var arr = ts.derive("ints", [ts.OBJECT]);
        arr.declareProperty("z", ts.STRING, true);
        arr.addMeta(new rs.AdditionalPropertyIs(ts.INTEGER));
        var s = arr.validateDirect({ z: "V" });
        assert.isTrue(s.isOk());
    });
    it("additional property 4", function () {
        var arr = ts.derive("ints", [ts.OBJECT]);
        arr.declareMapProperty(".", ts.STRING);
        arr.addMeta(new rs.AdditionalPropertyIs(ts.INTEGER));
        var s = arr.validateDirect({ z: "V" });
        assert.isTrue(s.isOk());
    });
    it("additional property +map", function () {
        var arr = ts.derive("ints", [ts.OBJECT]);
        arr.declareMapProperty("..", ts.STRING);
        arr.addMeta(new rs.AdditionalPropertyIs(ts.INTEGER));
        var s = arr.validateDirect({ z: "V" });
        assert.isTrue(!s.isOk());
    });
});
function assertLength(e, restr) {
    var newRestr = rs.optimize(restr);
    assert.equal(newRestr.length, e);
}
function assertNothing(restr) {
    var newRestr = rs.optimize(restr);
    assert.equal(newRestr.length, 1);
    assert.isTrue(newRestr[0] instanceof typesystem_1.NothingRestriction);
}
describe("Composition", function () {
    it("min max composition", function () {
        assertLength(1, [new rs.UniqueItems(true), new rs.UniqueItems(true)]);
        assertLength(2, [new rs.UniqueItems(true), new rs.MinItems(1)]);
    });
    it("property is 1", function () {
        assertLength(1, [new rs.PropertyIs("a", ts.SCALAR), new rs.PropertyIs("a", ts.NUMBER)]);
        assertLength(1, [new rs.PropertyIs("a", ts.NUMBER), new rs.PropertyIs("a", ts.SCALAR)]);
        var p1 = ts.deriveObjectType("Person");
        var p2 = ts.deriveObjectType("Person");
        assertLength(1, [new rs.PropertyIs("a", p1), new rs.PropertyIs("a", p2)]);
        assertNothing([new rs.PropertyIs("a", ts.NUMBER), new rs.PropertyIs("a", ts.BOOLEAN)]);
    });
    it("max properties composition", function () {
        assertNothing([new restrictions_1.MaxProperties(2), new restrictions_2.MinProperties(3)]);
        assertLength(1, [new restrictions_1.MaxProperties(3), new restrictions_1.MaxProperties(2)]);
        assertLength(1, [new restrictions_1.MaxProperties(2), new restrictions_1.MaxProperties(3)]);
        assertLength(2, [new restrictions_1.MaxProperties(6), new restrictions_2.MinProperties(3)]);
    });
    it("max length composition", function () {
        assertNothing([new restrictions_3.MaxLength(4), new restrictions_4.MinLength(6)]);
        assertLength(1, [new restrictions_3.MaxLength(3), new restrictions_3.MaxLength(2)]);
        assertLength(1, [new restrictions_3.MaxLength(2), new restrictions_3.MaxLength(3)]);
        assertLength(2, [new restrictions_3.MaxLength(6), new restrictions_2.MinProperties(3)]);
    });
    it("minimum composition", function () {
        assertNothing([new restrictions_5.Minimum(5), new restrictions_6.Maximum(2)]);
        assertLength(1, [new restrictions_5.Minimum(3), new restrictions_5.Minimum(2)]);
        assertLength(1, [new restrictions_5.Minimum(2), new restrictions_5.Minimum(3)]);
        assertLength(2, [new restrictions_5.Minimum(6), new restrictions_2.MinProperties(3)]);
    });
    it("maximum", function () {
        assertNothing([new restrictions_6.Maximum(1), new restrictions_5.Minimum(5)]);
        assertLength(1, [new restrictions_6.Maximum(3), new restrictions_6.Maximum(2)]);
        assertLength(1, [new restrictions_6.Maximum(2), new restrictions_6.Maximum(3)]);
        assertLength(2, [new restrictions_6.Maximum(6), new restrictions_2.MinProperties(3)]);
    });
    it("has property", function () {
        assertLength(1, [new restrictions_7.HasProperty("n"), new restrictions_7.HasProperty("n")]);
        assertLength(2, [new restrictions_7.HasProperty("n"), new restrictions_7.HasProperty("N")]);
    });
    it("component should be of type", function () {
        assertLength(1, [new restrictions_8.ComponentShouldBeOfType(ts.SCALAR), new restrictions_8.ComponentShouldBeOfType(ts.NUMBER)]);
        assertLength(1, [new restrictions_8.ComponentShouldBeOfType(ts.NUMBER), new restrictions_8.ComponentShouldBeOfType(ts.SCALAR)]);
        assertLength(2, [new restrictions_8.ComponentShouldBeOfType(ts.NUMBER), new restrictions_5.Minimum(2)]);
        var p1 = ts.deriveObjectType("Person");
        var p2 = ts.deriveObjectType("Person");
        assertLength(1, [new restrictions_8.ComponentShouldBeOfType(p1), new restrictions_8.ComponentShouldBeOfType(p2)]);
        assertNothing([new restrictions_8.ComponentShouldBeOfType(ts.NUMBER), new restrictions_8.ComponentShouldBeOfType(ts.BOOLEAN)]);
    });
    it("additional property test", function () {
        assertLength(1, [new restrictions_9.AdditionalPropertyIs(ts.SCALAR), new restrictions_9.AdditionalPropertyIs(ts.NUMBER)]);
        assertLength(1, [new restrictions_9.AdditionalPropertyIs(ts.NUMBER), new restrictions_9.AdditionalPropertyIs(ts.SCALAR)]);
        assertLength(2, [new restrictions_9.AdditionalPropertyIs(ts.NUMBER), new restrictions_5.Minimum(2)]);
        var p1 = ts.deriveObjectType("Person");
        var p2 = ts.deriveObjectType("Person");
        assertLength(1, [new restrictions_9.AdditionalPropertyIs(p1), new restrictions_9.AdditionalPropertyIs(p2)]);
        assertNothing([new restrictions_9.AdditionalPropertyIs(ts.NUMBER), new restrictions_9.AdditionalPropertyIs(ts.BOOLEAN)]);
    });
    it("map property is 1", function () {
        assertLength(1, [new restrictions_10.MapPropertyIs("a", ts.SCALAR), new restrictions_10.MapPropertyIs("a", ts.NUMBER)]);
        assertLength(1, [new restrictions_10.MapPropertyIs("a", ts.NUMBER), new restrictions_10.MapPropertyIs("a", ts.SCALAR)]);
        var p1 = ts.deriveObjectType("Person");
        var p2 = ts.deriveObjectType("Person");
        assertLength(1, [new restrictions_10.MapPropertyIs("a", p1), new restrictions_10.MapPropertyIs("a", p2)]);
        assertNothing([new restrictions_10.MapPropertyIs("a", ts.NUMBER), new restrictions_10.MapPropertyIs("a", ts.BOOLEAN)]);
    });
    it("typeof test", function () {
        assertLength(1, [new typesystem_2.TypeOfRestriction("number"), new typesystem_2.TypeOfRestriction("number")]);
        assertNothing([new typesystem_2.TypeOfRestriction("number"), new typesystem_2.TypeOfRestriction("boolean")]);
    });
    it("enum test", function () {
        assertNothing([new restrictions_11.Enum(["a", "b"]), new restrictions_11.Enum(["d", "c"])]);
        assertLength(1, [new restrictions_11.Enum(["a", "b"]), new restrictions_11.Enum(["b", "c"])]);
        assertLength(2, [new restrictions_11.Enum(["a", "b"]), new restrictions_2.MinProperties(2)]);
    });
    it("pattern", function () {
        assertLength(1, [new restrictions_12.Pattern("A"), new restrictions_12.Pattern("A")]);
        assertLength(2, [new restrictions_12.Pattern("a"), new restrictions_2.MinProperties(2)]);
    });
    it("min items", function () {
        assertNothing([new restrictions_13.MinItems(5), new restrictions_14.MaxItems(3)]);
        assertLength(1, [new restrictions_13.MinItems(2), new restrictions_13.MinItems(3)]);
        assertLength(1, [new restrictions_13.MinItems(3), new restrictions_13.MinItems(2)]);
        assertLength(2, [new restrictions_13.MinItems(3), new restrictions_14.MaxItems(4)]);
    });
    it("max items", function () {
        assertNothing([new restrictions_13.MinItems(5), new restrictions_14.MaxItems(3)]);
        assertLength(1, [new restrictions_14.MaxItems(2), new restrictions_14.MaxItems(3)]);
        assertLength(1, [new restrictions_14.MaxItems(3), new restrictions_14.MaxItems(2)]);
        assertLength(2, [new restrictions_13.MinItems(3), new restrictions_14.MaxItems(4)]);
    });
    it("min properties", function () {
        assertNothing([new restrictions_2.MinProperties(5), new restrictions_1.MaxProperties(3)]);
        assertLength(1, [new restrictions_1.MaxProperties(2), new restrictions_1.MaxProperties(3)]);
        assertLength(1, [new restrictions_1.MaxProperties(3), new restrictions_1.MaxProperties(2)]);
        assertLength(2, [new restrictions_1.MaxProperties(5), new restrictions_2.MinProperties(4)]);
    });
    it("min length composition", function () {
        assertNothing([new restrictions_3.MaxLength(4), new restrictions_4.MinLength(6)]);
        assertLength(1, [new restrictions_4.MinLength(3), new restrictions_4.MinLength(2)]);
        assertLength(1, [new restrictions_4.MinLength(2), new restrictions_4.MinLength(3)]);
        assertLength(2, [new restrictions_4.MinLength(6), new restrictions_2.MinProperties(3)]);
    });
});
describe("Type family", function () {
    it("type family 1", function () {
        var q = ts.deriveObjectType("Person");
        var q1 = ts.derive("Manager", [q]);
        var q2 = ts.derive("Executive", [q1]);
        var q3 = ts.derive("Rogue", [q]);
        var fam = q.typeFamily();
        assert.equal(fam.length, 4);
        assert.isTrue(fam.indexOf(q) != -1);
        assert.isTrue(fam.indexOf(q1) != -1);
        assert.isTrue(fam.indexOf(q2) != -1);
        assert.isTrue(fam.indexOf(q3) != -1);
    });
    it("type family 2", function () {
        var q = ts.deriveObjectType("Person");
        var q1 = ts.derive("Manager", [q]);
        var q2 = ts.derive("Executive", [q1]);
        var q3 = ts.deriveObjectType("Animal");
        var q4 = ts.union("PersonOrAnymal", [q, q3]);
        var family = q4.typeFamily();
        assert.equal(family.length, 4);
        assert.isTrue(family.indexOf(q2) != -1);
        assert.isTrue(family.indexOf(q3) != -1);
    });
    it("type family 3", function () {
        var q = ts.deriveObjectType("Person");
        q.addMeta(new ts.Abstract());
        var q1 = ts.derive("Manager", [q]);
        var q2 = ts.derive("Executive", [q1]);
        var q3 = ts.deriveObjectType("Animal");
        var q4 = ts.union("PersonOrAnymal", [q, q3]);
        var family = q4.typeFamily();
        assert.equal(family.length, 3);
        assert.isTrue(family.indexOf(q2) != -1);
        assert.isTrue(family.indexOf(q3) != -1);
    });
    it("type family 4", function () {
        var q = ts.deriveObjectType("Person");
        q.addMeta(new ts.Internal());
        var q1 = ts.derive("Manager", [q]);
        var q2 = ts.derive("Executive", [q1]);
        var q3 = ts.deriveObjectType("Animal");
        var q4 = ts.union("PersonOrAnymal", [q, q3]);
        var family = q4.typeFamily();
        assert.equal(family.length, 3);
        assert.isTrue(family.indexOf(q2) != -1);
        assert.isTrue(family.indexOf(q3) != -1);
    });
});
describe("Facet Registry", function () {
    it("All facets", function () {
        assert.equal(facetRegistry.getInstance().allPrototypes().length, 34);
    });
    it("All object facets", function () {
        assert.equal(facetRegistry.getInstance().applyableTo(ts.OBJECT).length, 22);
    });
    it("All meta", function () {
        assert.equal(facetRegistry.getInstance().allMeta().length, 13);
    });
});
describe("Automatic classification", function () {
    it("ac 1", function () {
        var t1 = ts.union("numberOrString", [ts.NUMBER, ts.STRING]);
        var t2 = ts.union("numberOrBoolean", [t1, ts.BOOLEAN]);
        t2.addMeta(new ts.Polymorphic());
        var t = t2.ac(false);
        assert.equal(t, ts.BOOLEAN);
        t = t2.ac(1);
        assert.equal(t, ts.NUMBER);
    });
    it("ac 2", function () {
        var t1 = ts.union("numberOrString", [ts.NUMBER, ts.STRING]);
        t1.addMeta(new ts.Polymorphic());
        var t = t1.ac(false);
        assert.equal(t, ts.NOTHING);
        t = t1.ac(1);
        assert.equal(t, ts.NUMBER);
    });
    it("ac 3", function () {
        var t1 = ts.derive("myNumber", [ts.NUMBER]);
        var t2 = ts.union("numberOrString", [t1, ts.STRING]);
        var t = t2.ac(false);
        assert.equal(t, ts.NOTHING);
        t = t2.ac(1);
        assert.equal(t, t1);
    });
    it("ac 4", function () {
        var t1 = ts.derive("myNumber", [ts.NUMBER]);
        t1.addMeta(new ts.Polymorphic());
        t1.addMeta(new ts.Abstract());
        var t = t1.ac(false);
        assert.equal(t, ts.NOTHING);
        t = t1.ac(1);
        assert.equal(t, ts.NOTHING);
    });
    it("ac 5", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.deriveObjectType("Person2");
        p1.declareProperty("x", ts.BOOLEAN, false);
        var p3 = ts.union("X", [p0, p1]);
        var tr = p3.ac({ x: true });
        assert.equal(tr, p1);
    });
    it("ac 6", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.deriveObjectType("Person2");
        p1.declareProperty("x", ts.STRING, false);
        var p3 = ts.union("X", [p0, p1]);
        var tr = p3.ac({ x: true });
        assert.equal(tr, ts.NOTHING);
    });
    it("ac 7", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var p3 = ts.union("X", [p0, p1]);
        var tr = p3.ac({ x: "d" });
        assert.equal(tr, p0);
    });
    it("ac 8", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d" });
        assert.equal(tr, p0);
    });
    it("ac 9", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ts.Polymorphic());
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d" });
        assert.equal(tr, p0);
    });
    it("ac 10", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ts.Polymorphic());
        p0.declareProperty("x", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b" });
        assert.equal(tr, p1);
    });
    it("ac 11", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ms.Discriminator("kind"));
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p0);
    });
    it("ac 12", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ms.Discriminator("kind"));
        p0.addMeta(new ms.DiscriminatorValue("Person2"));
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p0);
    });
    it("ac 13", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ts.Polymorphic());
        p0.addMeta(new ms.Discriminator("kind"));
        p0.addMeta(new ms.DiscriminatorValue("Person2"));
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.addMeta(new ms.DiscriminatorValue("Person"));
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p1);
    });
    it("ac 14", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ts.Polymorphic());
        p0.addMeta(new ts.Abstract());
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.addMeta(new ms.DiscriminatorValue("Person"));
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p1);
    });
    it("ac 15", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ts.Abstract());
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.addMeta(new ms.DiscriminatorValue("Person"));
        var p1 = ts.derive("Person3", [p0]);
        p1.addMeta(new ms.DiscriminatorValue("Person"));
        p1.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p0);
    });
    it("ac 16", function () {
        var p0 = ts.deriveObjectType("Person");
        p0.addMeta(new ms.Discriminator("kind"));
        p0.addMeta(new ts.Abstract());
        p0.declareProperty("x", ts.STRING, false);
        p0.declareProperty("kind", ts.STRING, false);
        var p1 = ts.derive("Person2", [p0]);
        p1.addMeta(new ms.DiscriminatorValue("Person"));
        var p2 = ts.derive("Person3", [p0]);
        p2.declareProperty("y", ts.STRING, false);
        var tr = p0.ac({ x: "d", y: "b", kind: "Person" });
        assert.equal(tr, p0);
    });
});
describe("TypeExpressions", function () {
    it("Literal is parsed correctly", function () {
        assert.equal(typeExpressions.parseToType("object", ts.builtInRegistry()), ts.OBJECT);
    });
    it("basic array type is parsed", function () {
        assert.isTrue(typeExpressions.parseToType("object[]", ts.builtInRegistry()).isSubTypeOf(ts.ARRAY));
    });
    it("basic union type is parsed", function () {
        assert.isTrue(typeExpressions.parseToType("number | string", ts.builtInRegistry()) instanceof ts.UnionType);
    });
    it("union type in parens is parsed", function () {
        assert.isTrue(typeExpressions.parseToType("(number | string)", ts.builtInRegistry()) instanceof ts.UnionType);
    });
    it("union type in parens + [] is parsed", function () {
        assert.isTrue(typeExpressions.parseToType("(number | string)[]", ts.builtInRegistry()).isSubTypeOf(ts.ARRAY));
    });
    it("incorrect expression", function () {
        assert.isTrue(typeExpressions.parseToType("ddd", ts.builtInRegistry()).isSubTypeOf(ts.UNKNOWN));
    });
    it("incorrect expression2", function () {
        assert.isTrue(typeExpressions.parseToType("((ddd", ts.builtInRegistry()).isSubTypeOf(ts.UNKNOWN));
    });
    it("Literal is stored correctly", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("object", ts.builtInRegistry())), "object");
    });
    it("basic array type is stored", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("object[]", ts.builtInRegistry())), "object[]");
    });
    it("basic union type is parsed", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("number | string", ts.builtInRegistry())), "number | string");
    });
    it("union type in parens is parsed", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("(number | string)", ts.builtInRegistry())), "number | string");
    });
    it("union type in parens + [] is stored correctly", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("(number | string)[]", ts.builtInRegistry())), "(number | string)[]");
    });
    it("incorrect expression stored", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("ddd[]", ts.builtInRegistry())), "ddd[]");
    });
    it("incorrect expression2 stored", function () {
        assert.equal(typeExpressions.storeToString(typeExpressions.parseToType("((ddd", ts.builtInRegistry())), "((ddd");
    });
});
describe("Extras", function () {
    it("has property accept null", function () {
        assert.isTrue(new rs.HasProperty("a").check(null).isOk());
    });
});
//# sourceMappingURL=builtInsTests.js.map