Example #1
0
        public void Test_AdvancedReferences()
        {
            AggregateTester.New()

            .Add("simple chain", () => ExpectOkReference("{ a: &TEST = $.b, b: $.c, c: $.d, d: OK }"))
            .Add("complex chain", () => ExpectOkReference("{ a: &TEST = $.b.an.an.a, b: { an: ^.c }, c: {an: ^.d }, d: { a: OK } }"))
            .Add("nested indices", () => ExpectOkReference("{ a: &TEST = $[$[$[0]]], [0]: 1, [1]: 2, [2]: OK }"))
            .Add("nested elements", () => ExpectOkReference("{ a: &TEST = $[#$[#$[#$[#$[4]]]]] }[ OK, 0, 1, 2, 3]"))
            .Add("combined indices", () => ExpectOkReference("{ a: &TEST = $[$[0, 0], $[1, 1]], [0, 0]: 0, [1, 1]: 1, [0, 1]: OK }"))

            // yeah, whatever
            .Add("reference spaghetti", () => ExpectOkReference(
                     "{ a: &TEST = $[0].ok, x: $[3]" +
                     ", zero: $.x.zero, [$.zero]: { ok: OK }" +
                     ", one: $.x.one, [$.one]: wtvr" +
                     ", two: $.x.two, [$.two]: wtvr" +
                     ", three: 3, [$.three]: { zero: 0, one: 1, two: 2 } }"
                     ))
            .Add("more spaghetti", () => ExpectOkReference(
                     "{ a: &TEST = $.x.^[0].ok, x: $[3]" +
                     ", zero: $.x.zero, [$[$.one]]: { ok: OK }" +
                     ", one: $.x.one, [$.one]: 0" +
                     ", two: $.x.two, [$.two]: wtvr" +
                     ", three: 3, [$.three]: { zero: 0, one: 1, two: 2 } }"
                     ))
            .Add("even more spaghetti", () => ExpectOkReference(
                     "{ a: &TEST = $.x.^[0].ok, x: $[3]" +
                     ", zero: $.x.zero, [$[# $.zero]]: { ok: OK }" +
                     ", one: $.x.one, [$.one]: wtvr" +
                     ", two: $.x.two, [$.two]: wtvr" +
                     ", three: 3, [$.three]: { zero: 0, one: 1, two: 2 } }[ 0 ]"
                     ))

            .Run();
        }
Example #2
0
        public void Test_StonExtensionElements()
        {
            AggregateTester.New()

            // all extensions unknown
            .Add("any extension type", () => ExpectUnknownExtension("!extension type", "extension", true))
            .Add("collection extension type", () => ExpectUnknownExtension("<!extension>[...] type", "extension", true))
            .Add("permitted extension type", () => ExpectUnknownExtension("!extension|regular type", "extension", true))
            .Add("nested extension type", () => ExpectUnknownExtension("regular<!extension> type", "extension", true))
            .Add("any extension member", () => ExpectUnknownExtension("{ !extension: member}", "extension", false))

            // extensions provided with whitelists
            .Add("known extension type", () => ExpectOkExtension("!extension type", new string[] { "extension" }, null, null, null))
            .Add("unknown extension type", () => ExpectUnknownExtension("!extension type", "extension", true, null, new string[] { "extension" }, null, null))
            .Add("known extension member", () => ExpectOkExtension("{ !extension: member}", null, new string[] { "extension" }, null, null))
            .Add("unknown extension member", () => ExpectUnknownExtension("{ !extension: member}", "extension", false, new string[] { "extension" }, null, null, null))
            .Add("both known extensions", () => ExpectOkExtension("{ !extension: !extension member}", new string[] { "extension" }, new string[] { "extension" }, null, null))

            // extensions provided with rules
            .Add("ruly extension type", () => ExpectOkExtension("!extension type", null, null, s => s.StartsWith("ex"), null))
            .Add("unruly extension type 1", () => ExpectUnknownExtension("!extension type", "extension", true, null, null, s => s.StartsWith("app"), null))
            .Add("unruly extension type 2", () => ExpectUnknownExtension("!extension type", "extension", true, null, null, null, s => s.StartsWith("ex")))
            .Add("ruly extension member", () => ExpectOkExtension("{ !extension: member}", null, null, null, s => s.StartsWith("ex")))
            .Add("unruly extension member 1", () => ExpectUnknownExtension("{ !extension: member}", "extension", false, null, null, null, s => s.StartsWith("app")))
            .Add("unruly extension member 2", () => ExpectUnknownExtension("{ !extension: member}", "extension", false, null, null, s => s.StartsWith("ex"), null))
            .Add("both ruly extensions", () => ExpectOkExtension("{ !extension: !extension member}", null, null, s => s.StartsWith("ex"), s => s.StartsWith("ex")))

            .Run();
        }
Example #3
0
        public void Test_NullEmptyContent()
        {
            AggregateTester.New()

            .Add("null null", () => ExpectValidValue(StonDataType.Null, null, "null"))
            .Add("null empty", () => ExpectValidValue(StonDataType.Null, "", "null"))

            .Add("number null", () => ExpectInvalidValue(StonDataType.Number, null, "A non-null simple value must be represented with an existing content."))
            .Add("number empty", () => ExpectInvalidValue(StonDataType.Number, "", "A number simple value cannot be empty."))

            .Add("binary null", () => ExpectInvalidValue(StonDataType.Binary, null, "A non-null simple value must be represented with an existing content."))
            .Add("binary empty", () => ExpectValidValue(StonDataType.Binary, "", "0n"))

            .Add("named null", () => ExpectInvalidValue(StonDataType.Named, null, "A non-null simple value must be represented with an existing content."))
            .Add("named empty", () => ExpectInvalidValue(StonDataType.Named, "", "A named simple value cannot be empty."))

            .Add("text null", () => ExpectInvalidValue(StonDataType.Text, null, "A non-null simple value must be represented with an existing content."))
            .Add("text empty", () => ExpectValidValue(StonDataType.Text, "", "\"\""))

            .Add("code null", () => ExpectInvalidValue(StonDataType.Code, null, "A non-null simple value must be represented with an existing content."))
            .Add("code empty", () => ExpectValidValue(StonDataType.Code, "", "``"))

            .Add("whatever null", () => ExpectInvalidValue((StonDataType)255, null, "A non-null simple value must be represented with an existing content."))
            .Add("whatever empty", () => ExpectInvalidValue((StonDataType)255, "", "Unknown simple value data type."))

            .Run();
        }
        public void Test_MalformedExceptions()
        {
            var glob1 = RegularStonReader.Default.ParseEntity("glob1");
            var glob2 = RegularStonReader.Default.ParseEntity("glob2");
            var glob3 = RegularStonReader.Default.ParseEntity("&GLOB3 = glob3");
            var glob4 = RegularStonReader.Default.ParseEntity("&GLOB4 = glob4");

            AggregateTester.New()

            // implementation exceptions
            .Add("null derived implementation interface", () => Expect.Exception <ArgumentException>(() => new StonImplementationException(typeof(object), typeof(object), typeof(object), null), "The derived interfaces list cannot contain any null."))

            // duplicate global entity exceptions
            .Add("non-duplicate global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob3, glob4), "The given entities have different global identifiers."))
            .Add("non-duplicate global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob3, glob4, "glob3 duplicates glob4"), "The given entities have different global identifiers."))
            .Add("non-duplicate global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob1, glob4), "The given entities have different global identifiers."))
            .Add("non-duplicate global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob1, glob4, "glob1 duplicates glob4"), "The given entities have different global identifiers."))
            .Add("duplicate non-global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob1, glob2), "The given entities have no global identifiers."))
            .Add("duplicate non-global entity", () => Expect.Exception <ArgumentException>(() => new StonDuplicateGlobalEntityException(glob1, glob2, "glob1 duplicates glob2"), "The given entities have no global identifiers."))

            // extensions exceptions
            .Add("non-named extension type", () => Expect.Exception <ArgumentException>(() => new StonExtensionTypeException(RegularStonReader.Default.ParseEntity("!array[...] []") as IStonValuedEntity), "The given entity has no extension type."))
            .Add("non-extension extension type", () => Expect.Exception <ArgumentException>(() => new StonExtensionTypeException(RegularStonReader.Default.ParseEntity("just type") as IStonValuedEntity), "The given entity has no extension type."))
            .Add("non-extension extension type 2", () => Expect.Exception <ArgumentException>(() => new StonExtensionTypeException((RegularStonReader.Default.ParseEntity("just type") as IStonValuedEntity).Type as IStonNamedType), "The given type is not an extension type."))

            .Add("non-extension extension member", () => Expect.Exception <ArgumentException>(() => new StonExtensionMemberException(new StonBindingName("name")), "The given member name is not an extension member name."))

            .Run();
        }
Example #5
0
        public void Test_GenericSyntaxErrors()
        {
            AggregateTester.New()

            // blank documents
            // mostly for testing reader position
            .Add("empty", () => Expect.UnexpectedCharacter("", -1, StonChartype.None, 0, 0, 0))
            .Add("spaces", () => Expect.UnexpectedCharacter("    ", -1, StonChartype.None, 0, 4, 4))
            .Add("tabs", () => Expect.UnexpectedCharacter("\t\t", -1, StonChartype.None, 0, 2, 2))
            .Add("cr", () => Expect.UnexpectedCharacter("\r\r", -1, StonChartype.None, 2, 0, 2))
            .Add("lf", () => Expect.UnexpectedCharacter("\n\n", -1, StonChartype.None, 2, 0, 2))
            .Add("crlf", () => Expect.UnexpectedCharacter("\r\n", -1, StonChartype.None, 1, 0, 2))
            .Add("lfcr", () => Expect.UnexpectedCharacter("\n\r", -1, StonChartype.None, 2, 0, 2))
            .Add("line comment", () => Expect.UnexpectedCharacter("//line", -1, StonChartype.None, 0, 6, 6))
            .Add("block comment", () => Expect.UnexpectedCharacter("/*\nblock\n*/", -1, StonChartype.None, 2, 2, 11))
            .Add("block co", () => Expect.UnexpectedCharacter("/*\nblock", -1, StonChartype.None, 1, 5, 8))
            .Add("almost", () => Expect.UnexpectedCharacter("/*\nalmost\n*", -1, StonChartype.None, 2, 1, 11))
            .Add("no comment", () => Expect.UnexpectedCharacter("/no comment", 'n', StonChartype.CommentDiscern, 0, 1, 1))

            // how unexpected!
            .Add("whatever", () => Expect.UnexpectedCharacter("(Habla español)", 'ñ', position: 11, message: "Nobody expected the Spanish Inquisition."))

            // multiple entities in a single STON text
            .Add("multiple entities", () => Expect.UnexpectedCharacter("{a:0}{b:1}", '{', StonChartype.EOS, 0, 5, 5, "Unexpected character after the valid entity: '{'."))
            .Add("multiple entities in document", () => Expect.Exception <StonUnexpectedCharacterParsingException>(() => RegularStonReader.Default.ParseDocument("{a:0}{b:1}"), "Unexpected character after the valid entity: '{'."))

            .Run();
        }
Example #6
0
        public void Test_DirectInitialContext()
        {
            AggregateTester.New()

            // reference defining initial context
            .Add("$", () => ExpectValidContext(new StonAncestorInitialContext(0), "$"))

            // ancestor initial context
            .Add("^", () => ExpectValidContext(new StonAncestorInitialContext(1), "^"))
            .Add("^^^^^", () => ExpectValidContext(new StonAncestorInitialContext(5), "^^^^^"))
            .Add("-^", () => ExpectInvalidContext(new StonAncestorInitialContext(-1), "An ancestor initial context must have a positive ancestor order."))
            .Add("-^^^...", () => ExpectInvalidContext(new StonAncestorInitialContext(int.MinValue), "An ancestor initial context must have a positive ancestor order."))

            // core initial context
            .Add("^*", () => ExpectValidContext(new StonGlobalEntityInitialContext(""), "^*"))

            // globally identified initial context
            .Add("agent007", () => ExpectValidContext(new StonGlobalEntityInitialContext("agent007"), "@agent007"))
            .Add("_GLOBAL", () => ExpectValidContext(new StonGlobalEntityInitialContext("_GLOBAL"), "@_GLOBAL"))
            .Add("007agent", () => ExpectInvalidContext(new StonGlobalEntityInitialContext("007agent"), "The global identifier \"007agent\" is not a valid CANUN identifier."))
            .Add("one.two", () => ExpectInvalidContext(new StonGlobalEntityInitialContext("one.two"), "The global identifier \"one.two\" is not a valid CANUN identifier."))
            .Add("what ever", () => ExpectInvalidContext(new StonGlobalEntityInitialContext("what ever"), "The global identifier \"what ever\" is not a valid CANUN identifier."))
            .Add(" ", () => ExpectInvalidContext(new StonGlobalEntityInitialContext(" "), "The global identifier \" \" is not a valid CANUN identifier."))
            .Add("☆", () => ExpectInvalidContext(new StonGlobalEntityInitialContext("☆"), "The global identifier \"☆\" is not a valid CANUN identifier."))

            .Run();
        }
Example #7
0
        public void Test_SyntacticallyInvalidReferences()
        {
            AggregateTester.New()

            // reference entities syntax errors
            .Add("explicitly typed reference entity", () => Expect.UnexpectedCharacter("{a: int $[0], [0]: value }", '$', StonChartype.None, 0, 8, 8))
            .Add("implicitly typed reference entity", () => Expect.UnexpectedCharacter("{a: <> $[0], [0]: value }", '$', StonChartype.None, 0, 7, 7))

            .Add("global index address subentity", () => Expect.UnexpectedCharacter("{a: $[&ID = 0], [0]: value }", '&', StonChartype.None, 0, 6, 6))
            .Add("global index address subentity 2", () => Expect.UnexpectedCharacter("{a: $[ID = 0], [0]: value }", '=', StonChartype.None, 0, 9, 9))
            .Add("mistyped index address subentity", () => Expect.UnexpectedCharacter("{a: $[char[] 'index'], [<char[]> 'index']: value }", ']', StonChartype.CollectionSuffixContinue, 0, 11, 11))
            .Add("complex index address subentity", () => Expect.UnexpectedCharacter("{a: $[(0,1)], [(0,1)]: value }", '(', StonChartype.None, 0, 6, 6))

            .Add("global collection element index", () => Expect.UnexpectedCharacter("{a: $[# &ID = 0] }[ ]", '&', StonChartype.Digit | StonChartype.Sign | StonChartype.AddressBegin, 0, 8, 8))
            .Add("global collection element index 2", () => Expect.UnexpectedCharacter("{a: $[# ID = 0] }[ ]", 'I', StonChartype.Digit | StonChartype.Sign | StonChartype.AddressBegin, 0, 8, 8))
            .Add("invalid collection element index type 1", () => Expect.UnexpectedCharacter("{a: $[# name], [name]: name}[ ]", 'n', StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign, 0, 8, 8))
            .Add("invalid collection element index type 2", () => Expect.UnexpectedCharacter("{a: $[# 'string'], ['string']: 'string'}[ ]", '\'', StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign, 0, 8, 8))
            .Add("invalid collection element index type 3", () => Expect.UnexpectedCharacter("{a: $[# `code`], [`code`]: `code`}[ ]", '`', StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign, 0, 8, 8))
            .Add("invalid collection element index type 4", () => Expect.UnexpectedCharacter("{a: $[# (0, 0)], [(0, 0)]: (0, 0)}[ ]", '(', StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign, 0, 8, 8))
            .Add("negative collection element index", () => Expect.Exception <StonParsingException>(() => RegularStonReader.Default.ParseEntity("{a: $[# -1], [-1]: -1}[ ]"), "Collection element index cannot be negative."))
            .Add("overly positive collection element index", () => Expect.UnexpectedCharacter("{a: $[# ++1], [1]: 1}[ 1 ]", '+', StonChartype.Digit, 0, 9, 9))
            .Add("invalid character collection element index", () => Expect.UnexpectedCharacter("{a: $[# +?], ['?']: '?'}[ '?' ]", '?', StonChartype.Digit, 0, 9, 9))

            .Run();
        }
Example #8
0
        public void Test_BareTypesDefinitions()
        {
            AggregateTester.New()

            .Add("<> implicit", () => ExpectType("<> implicit", null))
            .Add("lorem ipsum", () => ExpectType("lorem ipsum", "<\"lorem\">"))
            .Add("lorem (ipsum)", () => ExpectType("lorem (ipsum)", "<\"lorem\">"))
            .Add("lorem [ipsum]", () => ExpectType("lorem [ipsum]", "<\"lorem\">"))
            .Add("lorem|ipsum dolor", () => ExpectType("lorem|ipsum dolor", "<\"lorem\"|\"ipsum\">"))
            .Add("lorem|ipsum dolor", () => ExpectType("lorem|<ipsum> dolor", "<\"lorem\"|\"ipsum\">"))
            .Add("lorem|ipsum dolor", () => ExpectType("<lorem>|ipsum dolor", "<\"lorem\"|\"ipsum\">"))
            .Add("x = y z", () => ExpectType("x = y z", "<\"y\">"))

            // collection suffix can be tricky in bare types definition
            .Add("<int|string>[]", () => ExpectType("<int|string>[]", "<\"int\"|\"string\">"))
            .Add("<int|string>[...][]", () => ExpectType("<int|string>[...][]", "<<\"int\"|\"string\">[]>"))
            .Add("<int|string>[...][stuff]", () => ExpectType("<int|string>[...][stuff]", "<<\"int\"|\"string\">[]>"))
            .Add("<int|string>[][stuff]", () => Expect.UnexpectedCharacter("<int|string>[][stuff]", character: '[', position: 14))
            .Add("map<string, int> {}", () => ExpectType("map<string, int> {}", "<\"map\"<\"string\",\"int\">>"))
            .Add("map<string, int>[] {}", () => ExpectType("map<string, int>[] {}", "<\"map\"<\"string\",\"int\">>"))
            .Add("<<>|<type>> entity", () => Expect.UnexpectedCharacter("<<>|<type>> entity", character: '>', position: 2))

            .Add("map<string, int>[][]", () => Expect.UnexpectedCharacter("map<string, int>[][]", character: '[', position: 18))
            .Add("map<string, int>[...][...]", () => Expect.UnexpectedCharacter("map<string, int>[...][...]", character: -1))

            // miscellaneous type-related syntax errors
            .Add("! 'string'", () => Expect.UnexpectedCharacter("! 'string'", '\'', StonChartype.CanunBegin, 0, 2, 2))
            .Add("<>|<type> entity", () => Expect.UnexpectedCharacter("<>|<type> entity", character: '|', position: 2))
            .Add("<type>|<> entity", () => Expect.Exception <StonParsingException>(() => RegularStonReader.Default.ParseEntity("<type>|<> entity"), "Implicit type declaration has been read as a part of union type."))

            .Run();
        }
Example #9
0
        public void Test_BasicPathSegments()
        {
            AggregateTester.New()

            // ancestor access path segment
            .Add("ancestor1", () => ExpectOkReference("{ a: &TEST = @inb.^.x, b: { in: &inb=[], x: OK }, c: { in: [&inc=[]], x: CX }, d: { in: [[&ind=[]]], x: DX }}"))
            .Add("ancestor2", () => ExpectOkReference("{ a: &TEST = @inc.^^.x, b: { in: &inb=[], x: BX }, c: { in: [&inc=[]], x: OK }, d: { in: [[&ind=[]]], x: DX }}"))
            .Add("ancestor3", () => ExpectOkReference("{ a: &TEST = @ind.^^^.x, b: { in: &inb=[], x: BX }, c: { in: [&inc=[]], x: CX }, d: { in: [[&ind=[]]], x: OK }}"))
            .Add("unknown ancestor", () => ExpectUnknownReference("{ a: &TEST = @STOP.^^^^^.x, b: { in: &inb=[], x: BX }, c: { in: [&inc=[]], x: CX }, d: { in: [[&STOP = []]], x: DX }}", 0))

            // named member access path segment
            .Add("regular name", () => ExpectOkReference("{ a: &TEST = $.ext, ext: OK, !ext: EXTENSION }"))
            .Add("extension name", () => ExpectOkReference("{ a: &TEST = $.!ext, ext: REUGLAR, !ext: OK }"))
            .Add("regular name single quote", () => ExpectOkReference("{ a: &TEST = $.'ext', ext: OK, !ext: EXTENSION }"))
            .Add("extension name single quote", () => ExpectOkReference("{ a: &TEST = $.!'ext', ext: REUGLAR, !ext: OK }"))
            .Add("regular name double quote", () => ExpectOkReference("{ a: &TEST = $.\"ext\", ext: OK, !ext: EXTENSION }"))
            .Add("extension name double quote", () => ExpectOkReference("{ a: &TEST = $.!\"ext\", ext: REUGLAR, !ext: OK }"))
            .Add("no regular name", () => ExpectUnknownReference("&STOP = { a: &TEST = $.ext, !ext: EXTENSION }", 0))
            .Add("no extension name", () => ExpectUnknownReference("&STOP = { a: &TEST = $.!ext, ext: REUGLAR }", 0))
            .Add("no exclamation mark name", () => ExpectUnknownReference("&STOP = { a: &TEST = $.'!ext', !ext: EXTENSION }", 0))
            .Add("exclamation mark name", () => ExpectOkReference("{ a: &TEST = $.'!ext', \"!ext\": OK }"))

            .Add("simple entity named member access", () => ExpectUnknownReference("{ a: &TEST = $.b.c, b: &STOP = c }", 1))

            // indexed member access path segment
            .Add("index1", () => ExpectOkReference("{ a: &TEST = $[0], [0]: OK, [1]: ONE, [2]: TWO}"))
            .Add("index2", () => ExpectOkReference("{ a: &TEST = $[1], [0]: ZERO, [1]: OK, [2]: TWO}"))
            .Add("index3", () => ExpectOkReference("{ a: &TEST = $[2], [0]: ZERO, [1]: ONE, [2]: OK}"))
            .Add("index non", () => ExpectOkReference("{ a: &TEST = $[<> 0], [0]: OK, [int 0]: INT, [long 0]: LONG}"))
            .Add("index int", () => ExpectOkReference("{ a: &TEST = $[<int> 0], [0]: NON, [int 0]: OK, [long 0]: LONG}"))
            .Add("index long", () => ExpectOkReference("{ a: &TEST = $[<long> 0], [0]: NON, [int 0]: INT, [long 0]: OK}"))
            .Add("index short", () => ExpectUnknownReference("&STOP = { a: &TEST = $[<short> 0], [0]: NON, [int 0]: INT, [long 0]: LONG}", 0))
            .Add("index map<string,int>", () => ExpectOkReference("{ a: &TEST = $[<map<string,int>> 0], [0]: NON, [map<string,int> 0]: OK}"))
            .Add("index int|long", () => ExpectOkReference("{ a: &TEST = $[<int|long> 0], [0]: NON, [int|long 0]: OK }"))
            .Add("index int[]", () => ExpectOkReference("{ a: &TEST = $[<int[]> 0], [0]: NON, [int[...] 0]: OK}"))
            .Add("index ac", () => ExpectOkReference("{ test: &TEST = $[a,c], [a,c]: OK, [a,d]: AD, [b,c]: BC }"))
            .Add("index ad", () => ExpectOkReference("{ test: &TEST = $[a,d], [a,c]: AC, [a,d]: OK, [b,c]: BC }"))
            .Add("index bc", () => ExpectOkReference("{ test: &TEST = $[b,c], [a,c]: AC, [a,d]: AD, [b,c]: OK }"))
            .Add("index bd", () => ExpectUnknownReference("&STOP = { test: &TEST = $[b,d], [a,c]: AC, [a,d]: AD, [b,c]: BC }", 0))

            .Add("simple entity indexed member access", () => ExpectUnknownReference("{ a: &TEST = $[0][1], [0]: &STOP = 1 }", 1))

            // collection element access path segment
            .Add("element0", () => ExpectOkReference("[OK, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, &TEST = $[# 0]]"))
            .Add("element1", () => ExpectOkReference("[0, OK, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, &TEST = $[# 1]]"))
            .Add("element10", () => ExpectOkReference("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, OK, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, &TEST = $[# +10]]"))
            .Add("element17", () => ExpectOkReference("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, OK, 18, 19, 20, &TEST = $[# 0o21]]"))
            .Add("element int.max", () => ExpectUnknownReference("&STOP = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, &TEST = $[# 0x7fffffff]]", 0))

            .Add("simple entity collection element access", () => ExpectUnknownReference("{ a: &TEST = $[#0][#1], [0]: [a, b, c] }[ &STOP = d, e, f ]", 1))
            .Add("collectionless entity collection element access", () => ExpectUnknownReference("&STOP = { a: &TEST = $[#0], [0]: NOPE }", 0))
            .Add("complex element index", () => ExpectUnknownReference("&STOP = { a: &TEST = $[# $[#0]] }[ (1), (2) ]", 0, "The collection element index must be a simple value."))
            .Add("explicitly typed element index", () => ExpectUnknownReference("&STOP = { a: &TEST = $[# $[#0]] }[ int 1, int 2 ]", 0, "The collection element index must be implicitly typed."))
            .Add("invalid index data type", () => ExpectUnknownReference("&STOP = { a: &TEST = $[# $[#0]] }[ '1', '2' ]", 0, "The collection element index value must be of number or binary data type."))
            .Add("negative element index", () => ExpectUnknownReference("&STOP = { a: &TEST = $[# $[#0]] }[ -1, -2 ]", 0, "The collection element index must not be negative."))
            .Add("fractional element index", () => ExpectUnknownReference("&STOP = { a: &TEST = $[# $[#0]] }[ 1.5, 2.5 ]", 0, "The collection element index must not be fractional."))

            .Run();
        }
Example #10
0
        public void Test_DuplicateGlobalEntities()
        {
            AggregateTester.New()

            .Add("duplicate globals 1", () => ExpectDuplicateGlobalEntity("{ x: &DOUBLE = 0, y: &DOUBLE = 1 }", "DOUBLE"))
            .Add("duplicate globals 2", () => ExpectDuplicateGlobalEntity("{ x: &DOUBLE = 0, y: &DOUBLE = $.x }", "DOUBLE"))

            .Run();
        }
Example #11
0
        public void Test_ValuesTokenWriting()
        {
            AggregateTester.New()

            // newlines
            .Add("newline", () => ExpectString((writer) => writer.WriteLine(), "\n"))
            .Add("c newline", () => ExpectString((writer) => writer.WriteLine('c'), "c\n"))
            .Add("string newline", () => ExpectString((writer) => writer.WriteLine("string"), "string\n"))

            // string literals
            .Add("string delimiter '", () => ExpectString((writer) => writer.WriteStringLiteral("", '"'), "\"\""))
            .Add("string delimiter \"", () => ExpectString((writer) => writer.WriteStringLiteral("", '\''), "''"))
            .Add("string delimiter `", () => ExpectString((writer) => writer.WriteStringLiteral("", '`'), "``"))
            .Add("string delimiter ?", () => ExpectInvalidArgument((writer) => writer.WriteStringLiteral("", '?'), "The given character is not a valid STON text or code literal delimiter."))

            // binary literals
            .Add("binary base a", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("0123", 'a'), "Unknown base identfier: 'a'"))
            .Add("binary non-empty n", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("0123", 'n'), "An empty literal base identifier cannot be used for non-empty binary content."))

            .Add("binary binary", () => ExpectString((writer) => writer.WriteBinaryLiteral("0123456789abcdef", 'b'), "0b0000000100100011010001010110011110001001101010111100110111101111"))

            .Add("binary misaligned octal", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("80", 'o'), "The given binary content cannot be represented as a base 8 literal."))
            .Add("binary misaligned octal 2", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("40", 'o'), "The given binary content cannot be represented as a base 8 literal."))
            .Add("binary misaligned octal 3", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("8000", 'o'), "The given binary content cannot be represented as a base 8 literal."))
            .Add("binary aligned octal", () => ExpectString((writer) => writer.WriteBinaryLiteral("20", 'o'), "0o40"))
            .Add("binary aligned octal 2", () => ExpectString((writer) => writer.WriteBinaryLiteral("2000", 'o'), "0o20000"))
            .Add("binary aligned octal 3", () => ExpectString((writer) => writer.WriteBinaryLiteral("4000", 'o'), "0o40000"))

            .Add("binary hexadecimal", () => ExpectString((writer) => writer.WriteBinaryLiteral("0123456789abcdef", 'x'), "0x0123456789abcdef"))
            .Add("binary negative hexadecimal", () => ExpectString((writer) => writer.WriteBinaryLiteral("-0123456789abcdef", 'x'), "-0x0123456789abcdef"))
            .Add("binary uppercase", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("0123456789ABCDEF", 'x'), "A binary simple value content cannot have uppercase hexadecimal digits."))
            .Add("binary unknown", () => ExpectInvalidArgument((writer) => writer.WriteBinaryLiteral("0123456789?", 'x'), "A binary simple value content must be represented with hexadecimal digits."))

            .Add("binary base64 no padding", () => ExpectString((writer) => writer.WriteBinaryLiteral("123456", 'z'), "0zEjRW"))
            .Add("binary base64 one padding", () => ExpectString((writer) => writer.WriteBinaryLiteral("789a", 'z'), "0zeJo="))
            .Add("binary base64 two paddings", () => ExpectString((writer) => writer.WriteBinaryLiteral("bc", 'z'), "0zvA=="))

            // number literals
            .Add("number zero", () => ExpectNumbers("0", "0", "0e0", "0.0000e0"))
            .Add("number one", () => ExpectNumbers("1e0", "1", "1e0", "1.0000e0"))
            .Add("number hundred", () => ExpectNumbers("1e2", "100", "1e2", "1.0000e2"))
            .Add("number over the moon", () => ExpectNumbers("384e3", "384000", "3.84e5", "3.8400e5"))
            .Add("number thousandth", () => ExpectNumbers("1e-3", "0.001", "1e-3", "1.0000e-3"))
            .Add("number 123 thousandths", () => ExpectNumbers("123e-3", "0.123", "1.23e-1", "1.2300e-1"))
            .Add("number 1234567 thousandths", () => ExpectNumbers("1234567e-3", "1234.567", "1.234567e3", "1.234567e3"))

            .Add("minus one", () => ExpectNumbers("-1e0", "-1", "-1e0", "-1.0000e0"))
            .Add("minus hundred", () => ExpectNumbers("-1e2", "-100", "-1e2", "-1.0000e2"))
            .Add("minus over the moon", () => ExpectNumbers("-384e3", "-384000", "-3.84e5", "-3.8400e5"))
            .Add("minus thousandth", () => ExpectNumbers("-1e-3", "-0.001", "-1e-3", "-1.0000e-3"))
            .Add("minus 123 thousandths", () => ExpectNumbers("-123e-3", "-0.123", "-1.23e-1", "-1.2300e-1"))
            .Add("minus 1234567 thousandths", () => ExpectNumbers("-1234567e-3", "-1234.567", "-1.234567e3", "-1.234567e3"))

            .Run();
        }
Example #12
0
        public void Test_ConstructionOrder()
        {
            AggregateTester.New()

            .Add("valid construction", () => ExpectConstructionOrder("{ a: &LAST3 = ($.b, list: $.c), b: &NODE1 = ($[d]){ x: 0, y: 1 }, c: &NODE2 = ($.b)[3, 4, 5], [d]: &NODE0 = doodle }"))
            .Add("self-construction", () => ExpectCircularConstruction("&LAST0_1 = (null, ^*)"))
            .Add("constructioncursion", () => ExpectCircularConstruction("&NODE0_0 = (&NODE1_1 = (a, &NODE2_2 = (b, c, &LAST3_3 = (d, e, f, ^*))))"))
            .Add("construction pong", () => ExpectCircularConstruction("{ a: &NODE0_3 = (x, y, n1: z, n2: $.b), b: &NODE1_1 = (v, n3: &LAST2_0 = ($.a), n4: w)}"))

            .Run();
        }
Example #13
0
        public void Test_CircularReferences()
        {
            AggregateTester.New()

            .Add("direct self-reference", () => ExpectCircularReference("{ x: $.y, y: $.a, a: &LAST0_N = @LAST0_N }"))
            .Add("simple self-reference", () => ExpectCircularReference("{ x: $.y, y: $.a, a: &LAST0_0 = $.a }"))
            .Add("double self-reference", () => ExpectCircularReference("{ x: $.y, y: $.a, a: &NODE0_0 = $.b, b: &LAST1_0 = $.a }"))
            .Add("chaining self-reference", () => ExpectCircularReference("{ x: $.y, y: $.a, a: &NODE0_0 = $.b, b: &NODE1_1 = $.c.in, c: { in: &NODE2_2 = ^.d.in.in }, d: { in: { in: &LAST3_0 = ^^.a }} }"))

            .Run();
        }
        public void Test_EntityEquivalenceComparing()
        {
            var document       = RegularStonReader.Default.ParseDocument("{ a: A=0, b: B=0, c: C=(0,0), d: D=(0,0), e: E=int 0, ra: RA=@A, rb: RB=@B, rc: RC=@C, rd: RD=@D, re: RE=@E }");
            var entityComparer = new StonSemanticEntityEquivalenceComparer(document);
            var keyComparer    = new StonBindingKeyEquivalenceComparer(entityComparer);

            AggregateTester.New()

            .Add("A == RA", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "A", "RA")))
            .Add("B == RB", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "B", "RB")))
            .Add("C == RC", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "C", "RC")))
            .Add("D == RD", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "D", "RD")))
            .Add("E == RE", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "E", "RE")))

            .Add("A == B", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "A", "B")))
            .Add("A == B 2", () => Assert.IsTrue(AreEqual <IStonSimpleEntity>(document, entityComparer, "A", "B")))
            .Add("RA == RB", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "RA", "RB")))
            .Add("RA == RB 2", () => Assert.IsTrue(AreEqual <IStonReferenceEntity>(document, entityComparer, "RA", "RB")))

            .Add("A != E", () => Assert.IsFalse(AreEqual <IStonEntity>(document, entityComparer, "A", "E")))
            .Add("RA != RE", () => Assert.IsFalse(AreEqual <IStonEntity>(document, entityComparer, "RA", "RE")))

            .Add("C != D", () => Assert.IsFalse(AreEqual <IStonEntity>(document, entityComparer, "C", "D")))
            .Add("C != D 2", () => Assert.IsFalse(AreEqual <IStonComplexEntity>(document, entityComparer, "C", "D")))
            .Add("RC != RD", () => Assert.IsFalse(AreEqual <IStonEntity>(document, entityComparer, "RC", "RD")))
            .Add("RC != RD 2", () => Assert.IsFalse(AreEqual <IStonReferenceEntity>(document, entityComparer, "RC", "RD")))

            .Add("C == C", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "C", "C")))
            .Add("C == C 2", () => Assert.IsTrue(AreEqual <IStonComplexEntity>(document, entityComparer, "C", "C")))
            .Add("RC == RC", () => Assert.IsTrue(AreEqual <IStonEntity>(document, entityComparer, "RC", "RC")))
            .Add("RC == RC 2", () => Assert.IsTrue(AreEqual <IStonReferenceEntity>(document, entityComparer, "RC", "RC")))

            // null-valued entities are always equal
            .Add("null value == null value", () => Assert.IsTrue(entityComparer.Equals(
                                                                     new StonSimpleEntity(new StonSimpleValue(StonDataType.Null, null)),
                                                                     new StonSimpleEntity(new StonSimpleValue(StonDataType.Null, ""))
                                                                     )))

            // non-null references, one of which, being from outside, points to a null entity
            .Add("valid reference != invalid reference", () => Assert.IsFalse(entityComparer.Equals(document.GetGlobalEntity("RA"), new AReferenceEntity(null))))
            .Add("valid reference != invalid reference 2", () => Assert.IsFalse(entityComparer.Equals(document.GetGlobalEntity("RA") as IStonReferenceEntity, new AReferenceEntity(null))))

            .Run();

            // some additional assertions related to hash codes
            var set = new HashSet <IStonEntity>(entityComparer);

            Assert.IsTrue(set.Add(document.GetGlobalEntity("RA")));
            Assert.IsFalse(set.Add(document.GetGlobalEntity("A")));
            Assert.IsTrue(set.Add(document.GetGlobalEntity("E")));
            Assert.IsFalse(set.Add(document.GetGlobalEntity("RE")));
        }
Example #15
0
        public void Test_NullValues()
        {
            AggregateTester.New()

            .Add("null", () => ExpectParsedValue("null", StonDataType.Null, null))
            .Add("Null", () => ExpectParsedValue("Null", StonDataType.Named, "Null"))
            .Add("NULL", () => ExpectParsedValue("NULL", StonDataType.Named, "NULL"))
            .Add("some null", () => ExpectInvalidValue(StonDataType.Null, "some", "A null simple value must be represented with a non-existing or empty content."))

            .Run();

            // tests of null or empty null are in Test_NullEmptyContent
        }
Example #16
0
        public void Test_WrappedTypesDefinitions()
        {
            AggregateTester.New()

            .Add("<lorem> ipsum", () => ExpectType("lorem ipsum", "<\"lorem\">"))
            .Add("x = <y> z", () => ExpectType("x = <y> z", "<\"y\">"))
            .Add("<<<<<int>>>>> 0", () => ExpectType("<<<<<int>>>>> 0", "<\"int\">"))
            .Add("<<int|string>[...]> 0", () => ExpectType("<<int|string>[...]> 0", "<<\"int\"|\"string\">[]>"))
            .Add("<dictionary<string, int>> {}", () => ExpectType("<dictionary<string, int>> {}", "<\"dictionary\"<\"string\",\"int\">>"))
            .Add("<map<a|b, c|d>> {}", () => ExpectType("<map<a|b, c|d>> {}", "<\"map\"<\"a\"|\"b\",\"c\"|\"d\">>"))
            .Add("<map<a<<<b>>,c>[], d<e>|f[]>> {}", () => ExpectType("<map<a<<<b>>,c>[], d<e>|f[]>> {}", "<\"map\"<\"a\"<\"b\",\"c\">[],\"d\"<\"e\">|\"f\"[]>>"))

            .Run();
        }
        public void Test_ImpracticalScale()
        {
            AggregateTester.New()

            // accessing absurd collection indices
            .Add("colossal number collection index 1", () => Expect.Exception <NotSupportedException>(() => RegularStonReader.Default.ParseDocument("{ a: $[#2147483648] }[ 0 ]"), "The collection element index cannot be larger than maximum 32-bit signed integer value (2147483647)."))
            .Add("colossal number collection index 2", () => Expect.Exception <NotSupportedException>(() => RegularStonReader.Default.ParseDocument("{ a: $[# 1e11] }[ 0 ]"), "The collection element index cannot be larger than maximum 32-bit signed integer value (2147483647)."))
            .Add("colossal number collection index 3", () => Expect.Exception <NotSupportedException>(() => RegularStonReader.Default.ParseDocument("{ a: $[# 1234e9] }[ 0 ]"), "The collection element index cannot be larger than maximum 32-bit signed integer value (2147483647)."))
            .Add("colossal binary collection index", () => Expect.Exception <NotSupportedException>(() => RegularStonReader.Default.ParseDocument("{ a: $[# 0x80000000] }[ 0 ]"), "The collection element index cannot be larger than maximum 32-bit signed integer value (2147483647)."))

            // writing plain numbers
            .Add("plain colossal number", () => Expect.Exception <NotSupportedException>(() => MakeActor <StonTokenWriter>().WritePlainNumberLiteral("1e1000000000"), "A number that long cannot be written as a plain number literal."))
            .Add("plain tiny number", () => Expect.Exception <NotSupportedException>(() => MakeActor <StonTokenWriter>().WritePlainNumberLiteral("1e-1000000000"), "A number that long cannot be written as a plain number literal."))

            .Run();
        }
Example #18
0
        public void Test_BinaryValues()
        {
            AggregateTester.New()

            // syntactically valid values of all possible bases
            .Add("0n", () => ExpectParsedValue("0n", StonDataType.Binary, ""))
            .Add("-0n", () => ExpectParsedValue("-0n", StonDataType.Binary, ""))
            .Add("0   n", () => ExpectParsedValue("0   n", StonDataType.Binary, ""))
            .Add("0b 1010", () => ExpectParsedValue("0b 1010", StonDataType.Binary, "0a"))
            .Add("-0b 1010", () => ExpectParsedValue("-0b 1010", StonDataType.Binary, "-0a"))
            .Add("0b 010010 00100001", () => ExpectParsedValue("0b 010010 00100001", StonDataType.Binary, "1221"))
            .Add("0o 644", () => ExpectParsedValue("0o 644", StonDataType.Binary, "01a4"))
            .Add("-0o 644", () => ExpectParsedValue("-0o 644", StonDataType.Binary, "-01a4"))
            .Add("0o 12345670", () => ExpectParsedValue("0o 12345670", StonDataType.Binary, "29cbb8"))
            .Add("0x Feed Bed", () => ExpectParsedValue("0x Feed Bed", StonDataType.Binary, "0feedbed"))
            .Add("-0x Feed Bed", () => ExpectParsedValue("-0x Feed Bed", StonDataType.Binary, "-0feedbed"))
            .Add("0x 0123456789ABCDEFabcdef", () => ExpectParsedValue("0x 0123456789ABCDEFabcdef", StonDataType.Binary, "0123456789abcdefabcdef"))
            .Add("0x 0000", () => ExpectParsedValue("0x 0000", StonDataType.Binary, "0000"))
            .Add("-0x 0000", () => ExpectParsedValue("-0x 0000", StonDataType.Binary, "-0000"))
            .Add("0z No-padding", () => ExpectParsedValue("0z No-padding", StonDataType.Binary, "0368fa969d7629e0"))
            .Add("-0z No-padding", () => ExpectParsedValue("-0z No-padding", StonDataType.Binary, "-0368fa969d7629e0"))
            .Add("0z One-padding=", () => ExpectParsedValue("0z One-padding=", StonDataType.Binary, "3a77bea5a75d8a78"))
            .Add("0z One-padding", () => ExpectParsedValue("0z One-padding", StonDataType.Binary, "00e9defa969d7629e0"))
            .Add("0z 2-paddingg==", () => ExpectParsedValue("0z 2-paddingg==", StonDataType.Binary, "dbea5a75d8a782"))
            .Add("0z 2-paddingg", () => ExpectParsedValue("0z 2-paddingg", StonDataType.Binary, "0dbea5a75d8a7820"))

            // syntactically invalid binary values
            .Add("0b2", () => Expect.UnexpectedCharacter("0b2", '2', StonChartype.Base2, 0, 2, 2))
            .Add("0o8", () => Expect.UnexpectedCharacter("0o8", '8', StonChartype.Base8, 0, 2, 2))
            .Add("0xG", () => Expect.UnexpectedCharacter("0xG", 'G', StonChartype.Base16, 0, 2, 2))
            .Add("0z", () => Expect.UnexpectedCharacter("0z", -1, StonChartype.Base64, 0, 2, 2))
            .Add("0zZzz===", () => Expect.Exception <StonParsingException>(() => RegularStonReader.Default.ParseEntity("0zZzz==="), "Only one or two padding characters are allowed at the end of base 64 binary literal."))

            // directly created binary values
            .Add("=0", () => ExpectInvalidValue(StonDataType.Binary, "0", "A binary simple value content must have an even number of hexadecimal digits."))
            .Add("=00", () => ExpectValidValue(StonDataType.Binary, "00", "0x00"))
            .Add("=00ff", () => ExpectValidValue(StonDataType.Binary, "00ff", "0x00ff"))
            .Add("=-", () => ExpectInvalidValue(StonDataType.Binary, "-", "An empty binary simple value cannot be negative."))
            .Add("=-0", () => ExpectInvalidValue(StonDataType.Binary, "-0", "A binary simple value content must have an even number of hexadecimal digits."))
            .Add("=-00", () => ExpectValidValue(StonDataType.Binary, "-00", "-0x00"))
            .Add("=-0000", () => ExpectValidValue(StonDataType.Binary, "-0000", "-0x0000"))
            .Add("=feedem", () => ExpectInvalidValue(StonDataType.Binary, "feedem", "A binary simple value content must be represented with hexadecimal digits."))
            .Add("=00FF", () => ExpectInvalidValue(StonDataType.Binary, "00FF", "A binary simple value content cannot have uppercase hexadecimal digits."))

            .Run();
        }
Example #19
0
        public void Test_IndexAsCollectionElement()
        {
            AggregateTester.New()

            .Add("basic", () => ExpectOkReference("{ a: &TEST = $[0] }[ OK ]"))

            // direct numbers
            .Add("0 0", () => ExpectOkReference("{ a: &TEST = $[0], [0]: OK }[ NOPE ]"))
            .Add("0 0", () => ExpectOkReference("{ a: &TEST = $[0], [int 0]: NOPE }[ OK ]"))
            .Add("0x0 0", () => ExpectOkReference("{ a: &TEST = $[0x0], [0]: NOPE }[ OK ]"))
            .Add("#0 0", () => ExpectOkReference("{ a: &TEST = $[#0], [0]: NOPE }[ OK ]"))
            .Add("0 1", () => ExpectUnknownReference("&STOP = { a: &TEST = $[0], [1]: NOPE }[ NOPE ]", 0))
            .Add("0 0x0", () => ExpectOkReference("{ a: &TEST = $[0], [0x0]: NOPE }[ OK ]"))
            .Add("0x0 0x0", () => ExpectOkReference("{ a: &TEST = $[0x0], [0x0]: OK }[ NOPE ]"))
            .Add("0x0 0x0", () => ExpectOkReference("{ a: &TEST = $[0x0], [int 0x0]: NOPE }[ OK ]"))
            .Add("#0x0 0x0", () => ExpectOkReference("{ a: &TEST = $[#0x0], [0x0]: NOPE }[ OK ]"))
            .Add("0x0 0n", () => ExpectUnknownReference("&STOP = { a: &TEST = $[0x0], [0n]: NOPE }[ NOPE ]", 0))

            // references inside index path segment
            .Add("idx-0 0", () => ExpectOkReference("{ a: &TEST = $[$.idx], [0]: OK, idx: 0 }[ NOPE ]"))
            .Add("idx-0x0 0", () => ExpectOkReference("{ a: &TEST = $[$.idx], [0]: NOPE, idx: 0x0 }[ OK ]"))
            .Add("#idx-0 0", () => ExpectOkReference("{ a: &TEST = $[#$.idx], [0]: NOPE, idx: 0 }[ OK ]"))
            .Add("idx-0 1", () => ExpectUnknownReference("&STOP = { a: &TEST = $[$.idx], [1]: NOPE, idx: 0 }[ NOPE ]", 0))
            .Add("idx-0 0", () => ExpectOkReference("{ a: &TEST = $[$.idx], [0x0]: NOPE, idx: 0 }[ OK ]"))
            .Add("idx-0x0 0", () => ExpectOkReference("{ a: &TEST = $[$.idx], [0x0]: OK, idx: 0x0 }[ NOPE ]"))
            .Add("#idx-0 0", () => ExpectOkReference("{ a: &TEST = $[#$.idx], [0x0]: NOPE, idx: 0x0 }[ OK ]"))
            .Add("idx-0x0 0n", () => ExpectUnknownReference("&STOP = { a: &TEST = $[$.idx], [0n]: NOPE, idx: 0x0 }[ NOPE ]", 0))

            // references inside member index
            // the member index has an explicitly-typed string value
            // but since it's impossible to tell until the index reference is resolved
            // the indexed member path segment cannot be used as a collection element path segment
            .Add("0 ref", () => ExpectUnknownReference("&STOP = { a: &TEST = $[0], [$.ref]: NOPE, ref: string 'whatever' }[ NOPE ]", 0))
            .Add("0x0 ref", () => ExpectUnknownReference("&STOP = { a: &TEST = $[0x0], [$.ref]: NOPE, ref: string 'whatever' }[ NOPE ]", 0))
            .Add("#0 ref", () => ExpectOkReference("{ a: &TEST = $[#0], [$.ref]: NOPE, ref: string 'whatever' }[ OK ]"))
            .Add("#0x0 ref", () => ExpectOkReference("{ a: &TEST = $[#0x0], [$.ref]: NOPE, ref: string 'whatever' }[ OK ]"))
            .Add("idx-0 ref", () => ExpectUnknownReference("&STOP = { a: &TEST = $[$.idx], [$.ref]: NOPE, ref: string 'whatever', idx: 0 }[ NOPE ]", 0))
            .Add("idx-0x0 ref", () => ExpectUnknownReference("&STOP = { a: &TEST = $[$.idx], [$.ref]: NOPE, ref: 'string whatever', idx: 0x0 }[ NOPE ]", 0))
            .Add("#idx-0 ref", () => ExpectOkReference("{ a: &TEST = $[#$.idx], [$.ref]: NOPE, ref: string 'whatever', idx: 0 }[ OK ]"))
            .Add("#idx-0x0 ref", () => ExpectOkReference("{ a: &TEST = $[#$.idx], [$.ref]: NOPE, ref: string 'whatever', idx: 0x0 }[ OK ]"))

            .Run();
        }
Example #20
0
        public void Test_CanonicalWriter()
        {
            AggregateTester.New()

            .Add("canonical types", () => ExpectCanonicalForm(
                     "megatype<<param<a,b[]>>|<union|type>|<<union|collection>[]>|!'weird name'>[...] []",
                     "<\"megatype\"<\"param\"<\"a\",\"b\"[]>|<\"union\"|\"type\">|<\"union\"|\"collection\">[]|!\"weird name\">[]>[]"
                     ))
            .Add("canonical complex structure", () => ExpectCanonicalForm(
                     "(a, b, 'parameter x':c, y:d, 'z e e':e)[ one, two, three ]{ mem1: trollface, mem2: slender man, 'mem3 wow': doge, !ext: whatever, [idx,0]: i0, [idy,0]: i1, [idy,1]: i2, [idx,1]: i3 }",
                     "(:a,:b,\"parameter x\":c,\"y\":d,\"z e e\":e){\"mem1\":trollface,\"mem2\":<\"slender\">man,\"mem3 wow\":doge,!\"ext\":whatever,[idx,0]:i0,[idy,0]:i1,[idy,1e0]:i2,[idx,1e0]:i3}[one,two,three]"
                     ))
            .Add("canonical references", () => ExpectCanonicalForm(
                     "{ r1: $.s1 . x . !'etc.', r2: ^* . r3 . ^^ [# 0b10] , r3: @GLOBAL[local], s1: { x: { '!etc.':wtvr, !'etc.':stuff } }, s2: [arr, GLOBAL = { [local]: [^^]}, r2val] }",
                     "{\"r1\":$.\"s1\".\"x\".!\"etc.\",\"r2\":^*.\"r3\".^^[#0x02],\"r3\":@GLOBAL[local],\"s1\":{\"x\":{\"!etc.\":wtvr,!\"etc.\":stuff}},\"s2\":[arr,&GLOBAL={[local]:[^^]},r2val]}"
                     ))

            .Run();
        }
        public void Test_InvalidImplementations()
        {
            AggregateTester.New()

            // STON elements copying
            .Add("StonEntity.Copy(IStonEntity)", () => ExpectImplementationException(() => StonEntity.Copy(new InvalidStonEntity()), typeof(InvalidStonEntity), typeof(IStonEntity), typeof(IStonValuedEntity), typeof(IStonReferenceEntity)))
            .Add("StonValuedEntity.Copy(IStonValuedEntity)", () => ExpectImplementationException(() => StonValuedEntity.Copy(new InvalidStonValuedEntity()), typeof(InvalidStonValuedEntity), typeof(IStonValuedEntity), typeof(IStonSimpleEntity), typeof(IStonComplexEntity)))
            .Add("StonType.Copy(IStonType)", () => ExpectImplementationException(() => StonType.Copy(new InvalidStonType()), typeof(InvalidStonType), typeof(IStonType), typeof(IStonNamedType), typeof(IStonCollectionType), typeof(IStonUnionType)))
            .Add("StonBindingKey.Copy(IStonBindingKey)", () => ExpectImplementationException(() => StonBindingKey.Copy(new InvalidStonBindingKey()), typeof(InvalidStonBindingKey), typeof(IStonBindingKey), typeof(IStonBindingName), typeof(IStonBindingIndex)))
            .Add("StonInitialContext.Copy(IStonInitialContext)", () => ExpectImplementationException(() => StonInitialContext.Copy(new InvalidStonInitialContext()), typeof(InvalidStonInitialContext), typeof(IStonInitialContext), typeof(IStonAncestorInitialContext), typeof(IStonGlobalEntityInitialContext)))
            .Add("StonPathSegment.Copy(IStonPathSegment)", () => ExpectImplementationException(() => StonPathSegment.Copy(new InvalidStonPathSegment()), typeof(InvalidStonPathSegment), typeof(IStonPathSegment), typeof(IStonAncestorPathSegment), typeof(IStonMemberPathSegment), typeof(IStonCollectionElementPathSegment)))

            // entity writing
            .Add("write invalid entity", () => ExpectImplementationException(() => new InvalidStonEntity().ToCanonicalForm(), typeof(InvalidStonEntity), typeof(IStonEntity), typeof(IStonValuedEntity), typeof(IStonReferenceEntity)))
            .Add("write invalid valued entity", () => ExpectImplementationException(() => new InvalidStonValuedEntity().ToCanonicalForm(), typeof(InvalidStonValuedEntity), typeof(IStonValuedEntity), typeof(IStonSimpleEntity), typeof(IStonComplexEntity)))
            .Add("write invalid type", () => ExpectImplementationException(() => new ASimpleEntity(null, new InvalidStonType()).ToCanonicalForm(), typeof(InvalidStonType), typeof(IStonType), typeof(IStonNamedType), typeof(IStonCollectionType), typeof(IStonUnionType)))
            .Add("write invalid binding key", () => ExpectImplementationException(() =>
                                                                                  new AReferenceEntity(new AnAddress(new StonAncestorInitialContext(0), new IStonPathSegment[] { new AMemberSegment(new InvalidStonBindingKey()) })).ToCanonicalForm(),
                                                                                  typeof(InvalidStonBindingKey), typeof(IStonBindingKey), typeof(IStonBindingName), typeof(IStonBindingIndex))
                 )
            .Add("write invalid initial context", () => ExpectImplementationException(() =>
                                                                                      new AReferenceEntity(new AnAddress(new InvalidStonInitialContext(), new IStonPathSegment[] { })).ToCanonicalForm(),
                                                                                      typeof(InvalidStonInitialContext), typeof(IStonInitialContext), typeof(IStonAncestorInitialContext), typeof(IStonGlobalEntityInitialContext))
                 )
            .Add("write invalid path segment", () => ExpectImplementationException(() =>
                                                                                   new AReferenceEntity(new AnAddress(new StonAncestorInitialContext(0), new IStonPathSegment[] { new InvalidStonPathSegment() })).ToCanonicalForm(),
                                                                                   typeof(InvalidStonPathSegment), typeof(IStonPathSegment), typeof(IStonAncestorPathSegment), typeof(IStonMemberPathSegment), typeof(IStonCollectionElementPathSegment))
                 )

            // validation
            .Add("Validator.ValidateEntity(IStonEntity)", () => ExpectImplementationException(() => ValidateEntity(new InvalidStonEntity()), typeof(InvalidStonEntity), typeof(IStonEntity), typeof(IStonValuedEntity), typeof(IStonReferenceEntity)))
            .Add("Validator.ValidateEntity(IStonValuedEntity)", () => ExpectImplementationException(() => ValidateEntity(new InvalidStonValuedEntity()), typeof(InvalidStonValuedEntity), typeof(IStonValuedEntity), typeof(IStonSimpleEntity), typeof(IStonComplexEntity)))
            .Add("Validator.ValidateType(IStonType)", () => ExpectImplementationException(() => ValidateType(new InvalidStonType()), typeof(InvalidStonType), typeof(IStonType), typeof(IStonNamedType), typeof(IStonCollectionType), typeof(IStonUnionType)))
            .Add("Validator.ValidateBindingKey(IStonValuedEntity)", () => ExpectImplementationException(() => ValidateBindingKey(new InvalidStonBindingKey()), typeof(InvalidStonBindingKey), typeof(IStonBindingKey), typeof(IStonBindingName), typeof(IStonBindingIndex)))
            .Add("Validator.ValidateInitialContext(IStonEntity)", () => ExpectImplementationException(() => ValidateInitialContext(new InvalidStonInitialContext()), typeof(InvalidStonInitialContext), typeof(IStonInitialContext), typeof(IStonAncestorInitialContext), typeof(IStonGlobalEntityInitialContext)))
            .Add("Validator.ValidatePathSegment(IStonValuedEntity)", () => ExpectImplementationException(() => ValidatePathSegment(new InvalidStonPathSegment()), typeof(InvalidStonPathSegment), typeof(IStonPathSegment), typeof(IStonAncestorPathSegment), typeof(IStonMemberPathSegment), typeof(IStonCollectionElementPathSegment)))

            .Run();
        }
Example #22
0
        public void Test_InitialContexts()
        {
            AggregateTester.New()

            // testing for member initialization
            .Add("member self", () => ExpectOkReference("{ a: { a: { a: { a: &TEST = $.b, b: OK}, b: PAR1 }, b: PAR2 }, b: PAR3 }"))
            .Add("member par1", () => ExpectOkReference("{ a: { a: { a: { a: &TEST = ^.b, b: SELF}, b: OK }, b: PAR2 }, b: PAR3 }"))
            .Add("member par2", () => ExpectOkReference("{ a: { a: { a: { a: &TEST = ^^.b, b: SELF}, b: PAR1 }, b: OK }, b: PAR3 }"))
            .Add("member par3", () => ExpectOkReference("{ a: { a: { a: { a: &TEST = ^^^.b, b: SELF}, b: PAR1 }, b: PAR2 }, b: OK }"))
            .Add("member !par4", () => ExpectUnknownReference("{ a: { a: { a: { a: &TEST = ^^^^.b, b: SELF}, b: PAR1 }, b: PAR2 }, b: PAR3 }", -1))
            .Add("member core", () => ExpectOkReference("{ a: { a: { a: { a: &TEST = ^*.b, b: SELF}, b: PAR1 }, b: PAR2 }, b: OK }"))
            .Add("member global1", () => ExpectOkReference("{ a: &global = { a: { a: { a: &TEST = @global.b, b: SELF}, b: PAR1 }, b: OK }, b: PAR3 }"))
            .Add("member global2", () => ExpectOkReference("&global = { a: { a: { a: { a: &TEST = @global.b, b: SELF}, b: PAR1 }, b: PAR2 }, b: OK }"))
            .Add("member !global3", () => ExpectUnknownReference("{ a: { a: { a: { a: &TEST = @global.b, b: SELF}, b: PAR1 }, b: PAR2 }, b: PAR3 }", -1))

            // testing for collection initialization
            .Add("collection self", () => ExpectOkReference("[ [ [ [&TEST = $[#1], OK], PAR1], PAR2 ], PAR3]"))
            .Add("collection par1", () => ExpectOkReference("[ [ [ [&TEST = ^[#1], SELF], OK], PAR2 ], PAR3]"))
            .Add("collection par2", () => ExpectOkReference("[ [ [ [&TEST = ^^[#1], SELF], PAR1], OK ], PAR3]"))
            .Add("collection par3", () => ExpectOkReference("[ [ [ [&TEST = ^^^[#1], SELF], PAR1], PAR2 ], OK]"))
            .Add("collection !par4", () => ExpectUnknownReference("[ [ [ [&TEST = ^^^^[#1], SELF], PAR1], PAR2 ], PAR3]", -1))
            .Add("collection core", () => ExpectOkReference("[ [ [ [&TEST = ^*[#1], SELF], PAR1], PAR2 ], OK]"))
            .Add("collection global1", () => ExpectOkReference("[ &global = [ [ [&TEST = @global[#1], SELF], PAR1], OK ], PAR3]"))
            .Add("collection global2", () => ExpectOkReference("&global = [ [ [ [&TEST = @global[#1], SELF], PAR1], PAR2 ], OK]"))
            .Add("collection !global3", () => ExpectUnknownReference("[ [ [ [&TEST = @global[#1], SELF], PAR1], PAR2 ], PAR3]", -1))

            // testing for construction
            .Add("construction self", () => ExpectOkReference("[ [ [ (&TEST = $[#1], PARAM), OK], PAR1 ], PAR2]"))
            .Add("construction par1", () => ExpectOkReference("[ [ [ (&TEST = ^[#1], PARAM), SELF], OK ], PAR2]"))
            .Add("construction par2", () => ExpectOkReference("[ [ [ (&TEST = ^^[#1], PARAM), SELF], PAR1 ], OK]"))
            .Add("construction !par3", () => ExpectUnknownReference("[ [ [ (&TEST = ^^^[#1], PARAM), SELF], PAR1 ], PAR2]", -1))
            .Add("core construction !self", () => ExpectUnknownReference("(&TEST = $[#0])[NOPE]", -1))
            .Add("core construction core", () => ExpectOkReference("(&TEST = ^*[#0])[OK]"))

            .Run();
        }
Example #23
0
        public void Test_NamedValues()
        {
            AggregateTester.New()

            // parsed named values
            .Add("true", () => ExpectParsedValue("true", StonDataType.Named, "true"))
            .Add("false", () => ExpectParsedValue("false", StonDataType.Named, "false"))
            .Add("fa lse", () => ExpectParsedValue("fa lse", StonDataType.Named, "lse"))        // a named value "lse" of type "fa"
            .Add("One.Two.Three", () => ExpectParsedValue("One.Two.Three", StonDataType.Named, "One.Two.Three"))
            .Add("One  .Two.  Three", () => ExpectParsedValue("One  .Two.  Three", StonDataType.Named, "One.Two.Three"))
            .Add("One  .  Two  .  Three", () => ExpectParsedValue("One  .  Two  .  Three", StonDataType.Named, "One.Two.Three"))
            .Add("One  .  T  wo  .  Three", () => ExpectParsedValue("One  .  T  wo  .  Three", StonDataType.Named, "wo.Three"))         // a named value "wo.Three" of type "One.T"

            // directly created named values
            .Add("=single", () => ExpectValidValue(StonDataType.Named, "single", "single"))
            .Add("=dou.ble", () => ExpectValidValue(StonDataType.Named, "dou.ble", "dou.ble"))
            .Add("=.single", () => ExpectInvalidValue(StonDataType.Named, ".single", "A named simple value must be a valid CANUN path."))
            .Add("=single.", () => ExpectInvalidValue(StonDataType.Named, "single.", "A named simple value must be a valid CANUN path."))
            .Add("=dou..ble", () => ExpectInvalidValue(StonDataType.Named, "dou..ble", "A named simple value must be a valid CANUN path."))
            .Add("=0single", () => ExpectInvalidValue(StonDataType.Named, "0single", "A named simple value must be a valid CANUN path."))
            .Add("=dou.0ble", () => ExpectInvalidValue(StonDataType.Named, "dou.0ble", "A named simple value must be a valid CANUN path."))

            .Run();
        }
        public void Test_NullInvalidEquivalenceComparing()
        {
            var document       = RegularStonReader.Default.ParseDocument("{ a: A=0, b: B=0, c: C=(0,0), d: D=(0,0), e: E=int 0, ra: RA=@A, rb: RB=@B, rc: RC=@C, rd: RD=@D, re: RE=@E }");
            var typeComparer   = StonTypeEquivalenceComparer.Instance;
            var entityComparer = new StonSemanticEntityEquivalenceComparer(document);
            var keyComparer    = new StonBindingKeyEquivalenceComparer(entityComparer);

            AggregateTester.New()

            // comparing non-existing types

            .Add("null type == null type 1", () => Assert.IsTrue(typeComparer.Equals(null as IStonType, null as IStonType)))
            .Add("null type == null type 2", () => Assert.IsTrue(typeComparer.Equals(null as IStonNamedType, null as IStonNamedType)))
            .Add("null type == null type 3", () => Assert.IsTrue(typeComparer.Equals(null as IStonCollectionType, null as IStonCollectionType)))
            .Add("null type == null type 4", () => Assert.IsTrue(typeComparer.Equals(null as IStonUnionType, null as IStonUnionType)))

            .Add("null type != !null type 1", () => Assert.IsFalse(typeComparer.Equals(null as IStonType, new InvalidStonType())))
            .Add("null type != !null type 2", () => Assert.IsFalse(typeComparer.Equals(null as IStonNamedType, new ANamedType("", false, null))))
            .Add("null type != !null type 3", () => Assert.IsFalse(typeComparer.Equals(null as IStonCollectionType, new ACollectionType(null))))
            .Add("null type != !null type 4", () => Assert.IsFalse(typeComparer.Equals(null as IStonUnionType, new AUnionType(null))))
            .Add("invalid type != invalid type", () => Assert.IsFalse(typeComparer.Equals(new InvalidStonType(), new InvalidStonType())))

            /// hashing non-existing and invalid hashes
            .Add("null type hash 1", () => Assert.AreEqual(0, typeComparer.GetHashCode(null as IStonType)))
            .Add("null type hash 2", () => Assert.AreEqual(0, typeComparer.GetHashCode(null as IStonNamedType)))
            .Add("null type hash 3", () => Assert.AreEqual(0, typeComparer.GetHashCode(null as IStonCollectionType)))
            .Add("null type hash 4", () => Assert.AreEqual(0, typeComparer.GetHashCode(null as IStonUnionType)))
            .Add("invalid type hash", () => Assert.AreEqual(0, typeComparer.GetHashCode(new InvalidStonType())))

            // comparing non-existing and invalid entities
            .Add("null entity == null entity 1", () => Assert.IsTrue(entityComparer.Equals(null as IStonEntity, null as IStonEntity)))
            .Add("null entity == null entity 2", () => Assert.IsTrue(entityComparer.Equals(null as IStonValuedEntity, null as IStonValuedEntity)))
            .Add("null entity == null entity 3", () => Assert.IsTrue(entityComparer.Equals(null as IStonSimpleEntity, null as IStonSimpleEntity)))
            .Add("null entity == null entity 4", () => Assert.IsTrue(entityComparer.Equals(null as IStonComplexEntity, null as IStonComplexEntity)))
            .Add("null entity == null entity 5", () => Assert.IsTrue(entityComparer.Equals(null as IStonReferenceEntity, null as IStonReferenceEntity)))

            .Add("null entity != !null entity 1", () => Assert.IsFalse(entityComparer.Equals(null, new InvalidStonEntity())))
            .Add("null entity != !null entity 2", () => Assert.IsFalse(entityComparer.Equals(null, new InvalidStonValuedEntity())))
            .Add("null entity != !null entity 3", () => Assert.IsFalse(entityComparer.Equals(null, new ASimpleEntity(null))))
            .Add("null entity != !null entity 4", () => Assert.IsFalse(entityComparer.Equals(null, new AComplexEntity())))
            .Add("null entity != !null entity 5", () => Assert.IsFalse(entityComparer.Equals(null, new AReferenceEntity(null))))

            // hashing non-existing and invalid entities
            .Add("null entity hash 1", () => Assert.AreEqual(0, entityComparer.GetHashCode(null as IStonEntity)))
            .Add("null entity hash 2", () => Assert.AreEqual(0, entityComparer.GetHashCode(null as IStonValuedEntity)))
            .Add("null entity hash 3", () => Assert.AreEqual(0, entityComparer.GetHashCode(null as IStonSimpleEntity)))
            .Add("null entity hash 4", () => Assert.AreEqual(0, entityComparer.GetHashCode(null as IStonComplexEntity)))
            .Add("null entity hash 5", () => Assert.AreEqual(0, entityComparer.GetHashCode(null as IStonReferenceEntity)))
            .Add("invalid entity hash", () => Assert.AreEqual(0, entityComparer.GetHashCode(new InvalidStonEntity())))
            .Add("invalid valued entity hash", () => Assert.AreEqual(0, entityComparer.GetHashCode(new InvalidStonValuedEntity())))

            // comparing non-existing binding keys
            .Add("null key = null key", () => Assert.IsTrue(keyComparer.Equals(null as IStonBindingKey, null as IStonBindingKey)))
            .Add("null name = null name", () => Assert.IsTrue(keyComparer.Equals(null as IStonBindingName, null as IStonBindingName)))
            .Add("null index = null index", () => Assert.IsTrue(keyComparer.Equals(null as IStonBindingIndex, null as IStonBindingIndex)))

            .Add("null key != !null key", () => Assert.IsFalse(keyComparer.Equals(null as IStonBindingKey, new InvalidStonBindingKey())))
            .Add("null name != !null name", () => Assert.IsFalse(keyComparer.Equals(null as IStonBindingName, new StonBindingName("name", false))))
            .Add("null index != !null index", () => Assert.IsFalse(keyComparer.Equals(null as IStonBindingIndex, new ABindingIndex(null))))

            // hashing non-existing and invalid binding keys
            .Add("null key hash", () => Assert.AreEqual(0, keyComparer.GetHashCode(null as IStonBindingKey)))
            .Add("null name hash", () => Assert.AreEqual(0, keyComparer.GetHashCode(null as IStonBindingName)))
            .Add("null index hash", () => Assert.AreEqual(0, keyComparer.GetHashCode(null as IStonBindingIndex)))
            .Add("invalid key hash", () => Assert.AreEqual(0, keyComparer.GetHashCode(new InvalidStonBindingKey())))

            .Run();
        }
Example #25
0
        public void Test_DirectPathSegments()
        {
            AggregateTester.New()

            // ancestor path segment
            .Add(".", () => ExpectInvalidPathSegment(new StonAncestorPathSegment(0), "An ancestor path segment must have a positive ancestor order."))
            .Add(".^", () => ExpectValidPathSegment(new StonAncestorPathSegment(1), ".^"))
            .Add(".^^^^^", () => ExpectValidPathSegment(new StonAncestorPathSegment(5), ".^^^^^"))
            .Add(".-^", () => ExpectInvalidPathSegment(new StonAncestorPathSegment(-1), "An ancestor path segment must have a positive ancestor order."))
            .Add(".-^^^...", () => ExpectInvalidPathSegment(new StonAncestorPathSegment(int.MinValue), "An ancestor path segment must have a positive ancestor order."))

            // named member path segment
            .Add(".a", () => ExpectValidPathSegment(new StonMemberPathSegment(new StonBindingName("a")), ".\"a\""))
            .Add(".!''", () => ExpectValidPathSegment(new StonMemberPathSegment(new StonBindingName("", true)), ".!\"\""))
            .Add(".''", () => ExpectValidPathSegment(new StonMemberPathSegment(new StonBindingName("", false)), ".\"\""))
            .Add(".'in space'", () => ExpectValidPathSegment(new StonMemberPathSegment(new StonBindingName("in space")), ".\"in space\""))

            // indexed member path segment
            .Add("[]", () => ExpectInvalidPathSegment(new StonMemberPathSegment(new StonBindingIndex(Enumerable.Empty <IStonEntity>())), "A member binding index must be neither non-existing nor empty."))
            .Add("[&IDX = idx]", () => ExpectInvalidPathSegment(
                     new StonMemberPathSegment(new StonBindingIndex(new IStonEntity[] { _e("&IDX = idx") })),
                     "An indexed member path segment parameter cannot declare a global identifier."
                     ))
            .Add("[{idx: 0}]", () => ExpectInvalidPathSegment(
                     new StonMemberPathSegment(new StonBindingIndex(new IStonEntity[] { _e("{idx: 0}") })),
                     "An indexed member path segment parameter cannot be a complex-valued entity."
                     ))

            // collection element path segment
            .Add("[# &IDX = 0]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("&IDX = 0")),
                     "A collection element path segment index cannot declare a global identifier."
                     ))
            .Add("[# {idx: 0}]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("{idx: 0}")),
                     "A collection element path segment index cannot be a complex-valued entity."
                     ))
            .Add("[# int 0]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("int 0")),
                     "A collection element path segment index must be implicitly typed."
                     ))

            // implicitly typed number/binary entities are fine
            .Add("[# 0]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("0")), "[#0]"))
            .Add("[# 0x0]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("0x0")), "[#0x00]"))
            // negative indices pass the basic validation
            // but when document is built, they'll cause an error
            // also, they cannot be parsed by StonReader
            .Add("[# -1]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("-1")), "[#-1e0]"))
            .Add("[# -0x1]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("-0x01")), "[#-0x01]"))
            // references are always fine, until at document resolving it turns out otherwise
            .Add("[# $.idx]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("$.idx")), "[#$.\"idx\"]"))
            .Add("[# @IDX]", () => ExpectValidPathSegment(new StonCollectionElementPathSegment(_e("@IDX")), "[#@IDX]"))

            // non-number/non-binary simple values are not allowed
            .Add("[# null]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("null")),
                     "A collection element path segment index must have a number or binary value."
                     ))
            .Add("[# idx]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("idx")),
                     "A collection element path segment index must have a number or binary value."
                     ))
            .Add("[# '0']", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("'0'")),
                     "A collection element path segment index must have a number or binary value."
                     ))
            .Add("[# `0`]", () => ExpectInvalidPathSegment(
                     new StonCollectionElementPathSegment(_e("`0`")),
                     "A collection element path segment index must have a number or binary value."
                     ))

            .Run();
        }
        public void Test_InnerNull()
        {
            AggregateTester.New()

            // entity writing
            .Add("writing null entity", () => Expect.Exception <StonException>(() => new AComplexEntity(collectionInit: new ACollectionInit(new IStonEntity[] { null })).ToCanonicalForm(), "A non-existing entity has been found in the structure to be written."))


            .Add("writing null type", () => Expect.Exception <StonException>(() => new ASimpleEntity(null, new ANamedType("name", false, new IStonType[] { null })).ToCanonicalForm(), "A non-existing type has been found in the structure to be written."))
            .Add("writing null name", () => Expect.Exception <StonException>(() => new ASimpleEntity(null, new ANamedType(null, false, new IStonType[] { null })).ToCanonicalForm(), "A non-existing string has been found in the structure to be written."))
            .Add("writing named parameterless type", () => Expect.Exception <StonException>(() => new ASimpleEntity(null, new ANamedType("", false, null)).ToCanonicalForm(), "A named type cannot have a non-existing type parameters collection."))


            .Add("writing simple entity w/o value", () => Expect.Exception <StonException>(() => new ASimpleEntity(null).ToCanonicalForm(), "A simple-valued entity cannot have a non-existing value."))
            .Add("writing simple entity with unknown data type", () => Expect.Exception <StonException>(() => new ASimpleEntity(new StonSimpleValue((StonDataType)42, null)).ToCanonicalForm(), "Unknown simple value data type: 42."))


            .Add("writing construction w/o positional parameters",
                 () => Expect.Exception <StonException>(() => new AComplexEntity(construction: new AConstruction(null, null)).ToCanonicalForm(),
                                                        "A complex value construction cannot have a non-existing positional parameters collection."))
            .Add("writing construction w/o named parameters",
                 () => Expect.Exception <StonException>(() => new AComplexEntity(construction: new AConstruction(new IStonEntity[] { }, null)).ToCanonicalForm(),
                                                        "A complex value construction cannot have a non-existing named parameters collection."
                                                        ))
            .Add("writing member init w/o bindings", () => Expect.Exception <StonException>(() => new AComplexEntity(memberInit: new AMemberInit(null)).ToCanonicalForm(), "A complex value member initialization cannot have a non-existing member bindings collection."))
            .Add("writing null binding key", () => Expect.Exception <StonException>(
                     () => new AComplexEntity(memberInit: new AMemberInit(new KeyValuePair <IStonBindingKey, IStonEntity>[] { new KeyValuePair <IStonBindingKey, IStonEntity>() })).ToCanonicalForm(),
                     "A non-existing member binding key has been found in the structure to be written.")
                 )
            .Add("writing index w/o parameters", () => Expect.Exception <StonException>(
                     () => new AComplexEntity(memberInit: new AMemberInit(new KeyValuePair <IStonBindingKey, IStonEntity>[] { new KeyValuePair <IStonBindingKey, IStonEntity>(new ABindingIndex(null), null) })).ToCanonicalForm(),
                     "A member binding index cannot have non-existing parameters."
                     ))
            .Add("writing null entity", () => Expect.Exception <StonException>(() => new AComplexEntity(collectionInit: new ACollectionInit(null)).ToCanonicalForm(), "A complex value collection initialization cannot have a non-existing elements collection."))


            .Add("writing address w/o initial context", () => Expect.Exception <StonException>(() => new AReferenceEntity(new AnAddress(null, null)).ToCanonicalForm(), "A reference address cannot have a non-existing initial context."))
            .Add("writing address w/o relative path", () => Expect.Exception <StonException>(() => new AReferenceEntity(new AnAddress(new StonAncestorInitialContext(0), null)).ToCanonicalForm(), "A reference address cannot have a non-existing relative path."))
            .Add("writing global initial context w/o identifier",
                 () => Expect.Exception <StonException>(() => new AReferenceEntity(new AnAddress(new AGlobalContext(null), new IStonPathSegment[] { })).ToCanonicalForm(),
                                                        "A global entity initial context must have an existing global identifier."
                                                        ))
            .Add("writing path w/o segments", () => Expect.Exception <StonException>(() => new AReferenceEntity(new AnAddress(new StonAncestorInitialContext(0), new IStonPathSegment[] { null })).ToCanonicalForm(), "A non-existing path segment has been found in the structure to be written."))


            // validation
            .Add("validating unnamed type", () => Expect.Exception <StonException>(() => ValidateType(new ANamedType(null, false, null) as IStonType), "A named type cannot have a non-existing name."))
            .Add("validating named parameterless type", () => Expect.Exception <StonException>(() => ValidateType(new ANamedType("", false, null) as IStonType), "A named type cannot have a non-existing type parameters collection."))
            .Add("validating type w/ null parameters", () => Expect.Exception <StonException>(() => ValidateType(new ANamedType("", false, new IStonType[] { null }) as IStonType), "A named type cannot have a non-existing type parameter."))
            .Add("validating collection type w/o element type", () => Expect.Exception <StonException>(() => ValidateType(new ACollectionType(null) as IStonType), "A collection type cannot have a non-existing element type."))
            .Add("validating union type w/o permitted types", () => Expect.Exception <StonException>(() => ValidateType(new AUnionType(null) as IStonType), "A union type must have at least two permitted types."))
            .Add("validating union type w/ one null type", () => Expect.Exception <StonException>(() => ValidateType(new AUnionType(new IStonType[] { null }) as IStonType), "A union type must have at least two permitted types."))
            .Add("validating union type w/ several null types", () => Expect.Exception <StonException>(() => ValidateType(new AUnionType(new IStonType[] { null, null }) as IStonType), "A union type cannot have a non-existing permitted type."))

            .Add("validating null value", () => Expect.Exception <StonException>(() => ValidateEntity(new ASimpleEntity(null) as IStonEntity), "A simple-valued entity cannot have a non-existing value."))

            .Add("validating construction w/o positional parameters", () => Expect.Exception <StonException>(() => ValidateConstruction(new AConstruction(null, null)), "A complex value construction cannot have a non-existing positional parameters collection."))
            .Add("validating construction w/o named parameters", () => Expect.Exception <StonException>(() => ValidateConstruction(new AConstruction(new IStonEntity[] { }, null)), "A complex value construction cannot have a non-existing named parameters collection."))
            .Add("validating construction w/ null positional parameters",
                 () => Expect.Exception <StonException>(() => ValidateConstruction(new AConstruction(new IStonEntity[] { null }, new KeyValuePair <string, IStonEntity>[] { })),
                                                        "A complex value construction cannot have a non-existing parameter value."
                                                        ))
            .Add("validating construction w/ null named parameters",
                 () => Expect.Exception <StonException>(() => ValidateConstruction(new AConstruction(new IStonEntity[] { }, new KeyValuePair <string, IStonEntity>[] { new KeyValuePair <string, IStonEntity>("", null) })),
                                                        "A complex value construction cannot have a non-existing parameter value."
                                                        ))

            .Add("validating member init w/o bindings", () => Expect.Exception <StonException>(() => ValidateMemberInit(new AMemberInit(null)), "A complex value member initialization cannot have a non-existing member bindings collection."))
            .Add("validating member init w/ null bindings", () => Expect.Exception <StonException>(
                     () => ValidateMemberInit(new AMemberInit(new KeyValuePair <IStonBindingKey, IStonEntity>[] { new KeyValuePair <IStonBindingKey, IStonEntity>(new ABindingName("", false), null) })),
                     "A complex value member initialization cannot have non-existing member values."
                     ))
            .Add("validating binding name w/o name", () => Expect.Exception <StonException>(() => ValidateBindingKey(new ABindingName(null, false) as IStonBindingKey), "A member binding name cannot have non-existing name."))
            .Add("validating binding index w/o parameters", () => Expect.Exception <StonException>(() => ValidateBindingKey(new ABindingIndex(null) as IStonBindingKey), "A member binding index must be neither non-existing nor empty."))
            .Add("validating binding name w/ null parameters", () => Expect.Exception <StonException>(() => ValidateBindingKey(new ABindingIndex(new IStonEntity[] { null }) as IStonBindingKey), "A member binding index cannot have non-existing index parameters."))

            .Add("validating collection init w/o elements", () => Expect.Exception <StonException>(() => ValidateCollectionInit(new ACollectionInit(null)), "A complex value collection initialization cannot have a non-existing elements collection."))
            .Add("validating collection init w/ null elements", () => Expect.Exception <StonException>(() => ValidateCollectionInit(new ACollectionInit(new IStonEntity[] { null })), "A complex value collection initialization cannot have non-existing elements."))

            .Add("validating null address", () => Expect.Exception <StonException>(() => ValidateEntity(new AReferenceEntity(null) as IStonEntity), "A reference entity cannot have a non-existing address."))
            .Add("validating address w/o initial context", () => Expect.Exception <StonException>(() => ValidateAddress(new AnAddress(null, null)), "A reference address cannot have a non-existing initial context."))
            .Add("validating address w/o relative path", () => Expect.Exception <StonException>(() => ValidateAddress(new AnAddress(new StonAncestorInitialContext(0), null)), "A reference address cannot have a non-existing relative path."))
            .Add("validating address w/ null path segments", () => Expect.Exception <StonException>(() => ValidateAddress(new AnAddress(new StonAncestorInitialContext(0), new IStonPathSegment[] { null })), "A reference address relative path cannot have non-existing path segments."))
            .Add("validating null global context", () => Expect.Exception <StonException>(() => ValidateInitialContext(new AGlobalContext(null) as IStonInitialContext), "A global entity initial context must have an existing global identifier."))
            .Add("validating member segment w/o key", () => Expect.Exception <StonException>(() => ValidatePathSegment(new AMemberSegment(null) as IStonPathSegment), "A member path segment cannot have a non-existing binding key."))
            .Add("validating element segment w/o key", () => Expect.Exception <StonException>(() => ValidatePathSegment(new AnElementSegment(null) as IStonPathSegment), "A collection element path segment cannot have a non-existing element index."))

            .Run();
        }
        public void Test_ArgumentNull()
        {
            // things would have been a great deal easier if the non-nullable reference type was implemented already...

            AggregateTester.New()

            // STON elements construction
            .Add("new StonSimpleEntity.Copy(value)", () => ExpectArgumentNull(() => new StonSimpleEntity(null as IStonSimpleValue), "value"))
            .Add("new StonReferenceEntity(address,globalIdentifier)", () => ExpectArgumentNull(() => new StonReferenceEntity(null as IStonAddress), "address"))

            .Add("new StonNamedType.Copy(name,typeParameters,isExtension)", () => ExpectArgumentNull(() => new StonNamedType(null as string), "name"))
            .Add("new StonCollectionType.Copy(elementType)", () => ExpectArgumentNull(() => new StonCollectionType(null as IStonType), "elementType"))
            .Add("new StonUnionType(permittedTypes)", () => ExpectArgumentNull(() => new StonUnionType(null as IEnumerable <IStonType>), "permittedTypes"))

            .Add("new StonSimpleValue(value)", () => ExpectArgumentNull(() => StonSimpleValue.Copy(null), "value"))

            .Add("new StonBindingName(name,isExtension)", () => ExpectArgumentNull(() => new StonBindingName(null as string), "name"))
            .Add("new StonBindingIndex(bindingIndex)", () => ExpectArgumentNull(() => new StonBindingIndex(null as IEnumerable <IStonEntity>), "parameters"))

            .Add("new StonAddress(initialContext,relativePath)", () => ExpectArgumentNull(() => new StonAddress(null, null), "initialContext"))
            .Add("new StonGlobalEntityInitialContext(globalIdentifier)", () => ExpectArgumentNull(() => new StonGlobalEntityInitialContext(null as string), "globalIdentifier"))
            .Add("new StonMemberPathSegment(bindingKey)", () => ExpectArgumentNull(() => new StonMemberPathSegment(null as IStonBindingKey), "bindingKey"))
            .Add("new StonCollectionElementPathSegment(bindingKey)", () => ExpectArgumentNull(() => new StonCollectionElementPathSegment(null as IStonEntity), "elementIndex"))

            // STON elements copying
            .Add("StonEntity.Copy(entity)", () => ExpectArgumentNull(() => StonEntity.Copy(null), "entity"))
            .Add("StonValuedEntity.Copy(entity)", () => ExpectArgumentNull(() => StonValuedEntity.Copy(null), "entity"))
            .Add("StonSimpleEntity.Copy(entity)", () => ExpectArgumentNull(() => StonSimpleEntity.Copy(null), "entity"))
            .Add("StonComplexEntity.Copy(entity)", () => ExpectArgumentNull(() => StonComplexEntity.Copy(null), "entity"))
            .Add("StonReferenceEntity.Copy(entity)", () => ExpectArgumentNull(() => StonReferenceEntity.Copy(null), "entity"))

            .Add("StonType.Copy(type)", () => ExpectArgumentNull(() => StonType.Copy(null), "type"))
            .Add("StonNamedType.Copy(type)", () => ExpectArgumentNull(() => StonNamedType.Copy(null), "type"))
            .Add("StonCollectionType.Copy(type)", () => ExpectArgumentNull(() => StonCollectionType.Copy(null), "type"))
            .Add("StonUnionType.Copy(type)", () => ExpectArgumentNull(() => StonUnionType.Copy(null), "type"))

            .Add("StonSimpleValue.Copy(value)", () => ExpectArgumentNull(() => StonSimpleValue.Copy(null), "value"))

            .Add("StonConstruction.Copy(construction)", () => ExpectArgumentNull(() => StonConstruction.Copy(null), "construction"))
            .Add("StonMemberInit.Copy(memberInit)", () => ExpectArgumentNull(() => StonMemberInit.Copy(null), "memberInit"))
            .Add("StonBindingKey.Copy(bindingKey)", () => ExpectArgumentNull(() => StonBindingKey.Copy(null), "bindingKey"))
            .Add("StonBindingName.Copy(bindingName)", () => ExpectArgumentNull(() => StonBindingName.Copy(null), "bindingName"))
            .Add("StonBindingIndex.Copy(bindingIndex)", () => ExpectArgumentNull(() => StonBindingIndex.Copy(null), "bindingIndex"))
            .Add("StonCollectionInit.Copy(collectionInit)", () => ExpectArgumentNull(() => StonCollectionInit.Copy(null), "collectionInit"))

            .Add("StonAddress.Copy(address)", () => ExpectArgumentNull(() => StonAddress.Copy(null), "address"))
            .Add("StonInitialContext.Copy(context)", () => ExpectArgumentNull(() => StonInitialContext.Copy(null), "context"))
            .Add("StonAncestorInitialContext.Copy(context)", () => ExpectArgumentNull(() => StonAncestorInitialContext.Copy(null), "context"))
            .Add("StonGlobalEntityInitialContext.Copy(context)", () => ExpectArgumentNull(() => StonGlobalEntityInitialContext.Copy(null), "context"))
            .Add("StonPathSegment.Copy(segment)", () => ExpectArgumentNull(() => StonPathSegment.Copy(null), "segment"))
            .Add("StonAncestorPathSegment.Copy(segment)", () => ExpectArgumentNull(() => StonAncestorPathSegment.Copy(null), "segment"))
            .Add("StonMemberPathSegment.Copy(segment)", () => ExpectArgumentNull(() => StonMemberPathSegment.Copy(null), "segment"))
            .Add("StonCollectionElementPathSegment.Copy(segment)", () => ExpectArgumentNull(() => StonCollectionElementPathSegment.Copy(null), "segment"))

            // document methods
            .Add("StonDocument.GetParentContext(context)", () => ExpectArgumentNull <IStonDocument>((document) => document.GetParentContext(null), "context"))
            .Add("StonDocument.GetMember(entity?,memberKey)", () => ExpectArgumentNull <IStonDocument>((document) => document.GetMember(null, null), "entity"))
            .Add("StonDocument.GetMember(entity,memberKey?)", () => ExpectArgumentNull <IStonDocument>((document) => document.GetMember(document.Core as IStonComplexEntity, null), "memberKey"))
            .Add("StonDocument.GetReferencedValue(reference)", () => ExpectArgumentNull <IStonDocument>((document) => document.GetReferencedValue(null), "reference"))

            // reading/writing
            .Add("new StonReader(elementFactory?,documentFactory)", () => ExpectArgumentNull(() => new RegularStonReader(null, null), "elementFactory"))
            .Add("new StonReader(elementFactory,documentFactory?)", () => ExpectArgumentNull(() => new RegularStonReader(Building.CoreStonElementFactory.Instance, null), "documentFactory"))
            .Add("StonReader.ReadEntity(reader)", () => ExpectArgumentNull(() => RegularStonReader.Default.ReadEntity(null), "reader"))
            .Add("StonReader.ReadDocument(reader,...)", () => ExpectArgumentNull(() => RegularStonReader.Default.ReadDocument(null), "reader"))

            .Add("new StonTokenReader(innerReader)", () => ExpectArgumentNull(() => new StonTokenReader(null), "innerReader"))

            .Add("*IStonReader.ParseEntity(value)", () => ExpectArgumentNull(() => (RegularStonReader.Default as IStonReader).ParseEntity(null), "value"))
            .Add("*IStonReader.ParseEntity<>(value)", () => ExpectArgumentNull(() => RegularStonReader.Default.ParseEntity(null), "value"))
            .Add("*IStonReader.LoadEntity(stream)", () => ExpectArgumentNull(() => (RegularStonReader.Default as IStonReader).LoadEntity(null as Stream), "stream"))
            .Add("*IStonReader.LoadEntity<>(stream)", () => ExpectArgumentNull(() => RegularStonReader.Default.LoadEntity(null as Stream), "stream"))
            .Add("*IStonReader.ParseDocument(value)", () => ExpectArgumentNull(() => (RegularStonReader.Default as IStonReader).ParseDocument(null), "value"))
            .Add("*IStonReader.ParseDocument<>(value)", () => ExpectArgumentNull(() => RegularStonReader.Default.ParseDocument(null), "value"))
            .Add("*IStonReader.LoadDocument(stream)", () => ExpectArgumentNull(() => (RegularStonReader.Default as IStonReader).LoadDocument(null as Stream), "stream"))
            .Add("*IStonReader.LoadDocument<>(stream)", () => ExpectArgumentNull(() => RegularStonReader.Default.LoadDocument(null as Stream), "stream"))

            .Add("new StonTokenWriter(innerWriter)", () => ExpectArgumentNull(() => new StonTokenWriter(null), "innerWriter"))
            .Add("StonTokenWriter.WriteStringLiteral(content,delimiter)", () => ExpectArgumentNull((StonTokenWriter writer) => writer.WriteStringLiteral(null), "content"))
            .Add("StonTokenWriter.WriteBinaryLiteral(content,baseId)", () => ExpectArgumentNull((StonTokenWriter writer) => writer.WriteBinaryLiteral(null), "content"))
            .Add("StonTokenWriter.WriteCanonicalNumberLiteral(content)", () => ExpectArgumentNull((StonTokenWriter writer) => writer.WriteCanonicalNumberLiteral(null), "content"))
            .Add("StonTokenWriter.WritePlainNumberLiteral(content)", () => ExpectArgumentNull((StonTokenWriter writer) => writer.WritePlainNumberLiteral(null), "content"))
            .Add("StonTokenWriter.WriteScientificNumberLiteral(content)", () => ExpectArgumentNull((StonTokenWriter writer) => writer.WriteScientificNumberLiteral(null), "content"))

            .Add("CanonicalStonWriter.WriteEntity(writer?,entity)", () => ExpectArgumentNull(() => CanonicalStonWriter.Instance.WriteEntity(null, null), "writer"))
            .Add("CanonicalStonWriter.WriteEntity(writer,entity?)", () => ExpectArgumentNull(() => CanonicalStonWriter.Instance.WriteEntity(new System.IO.StringWriter(), null), "entity"))
            .Add("CanonicalStonWriter.WriteDocument(writer?,document)", () => ExpectArgumentNull(() => CanonicalStonWriter.Instance.WriteDocument(null, null), "writer"))
            .Add("CanonicalStonWriter.WriteDocument(writer,document?)", () => ExpectArgumentNull(() => CanonicalStonWriter.Instance.WriteDocument(new System.IO.StringWriter(), null), "document"))

            .Add("*IStonEntity.ToString(writer)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.ToString(null), "writer"))
            .Add("*IStonEntity.ToString<>(writer)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.ToString(null as IStonWriter <IStonEntity, IStonDocument>), "writer"))
            .Add("*IStonEntity.Save(stream?,writer)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.Save(null as Stream, CanonicalStonWriter.Instance), "stream"))
            .Add("*IStonEntity.Save(stream,writer?)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.Save(new MemoryStream(), null), "writer"))
            .Add("*IStonEntity.Save<>(stream?,writer)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.Save(null as Stream, null as IStonWriter <IStonEntity, IStonDocument>), "stream"))
            .Add("*IStonEntity.Save<>(stream,writer?)", () => ExpectArgumentNull <IStonEntity>((entity) => entity.Save(new MemoryStream(), null as IStonWriter <IStonEntity, IStonDocument>), "writer"))
            .Add("*IStonDocument.ToString(writer)", () => ExpectArgumentNull <IStonDocument>((document) => document.ToString(null), "writer"))
            .Add("*IStonDocument.ToString<>(writer)", () => ExpectArgumentNull <IStonDocument>((document) => document.ToString(null as IStonWriter <IStonEntity, IStonDocument>), "writer"))
            .Add("*IStonDocument.Save(stream?,writer)", () => ExpectArgumentNull <IStonDocument>((document) => document.Save(null as Stream, null), "stream"))
            .Add("*IStonDocument.Save(stream,writer?)", () => ExpectArgumentNull <IStonDocument>((document) => document.Save(new MemoryStream(), null), "writer"))
            .Add("*IStonDocument.Save<>(stream?,writer)", () => ExpectArgumentNull <IStonDocument>((document) => document.Save(null as Stream, null as IStonWriter <IStonEntity, IStonDocument>), "stream"))
            .Add("*IStonDocument.Save<>(stream,writer?)", () => ExpectArgumentNull <IStonDocument>((document) => document.Save(new MemoryStream(), null as IStonWriter <IStonEntity, IStonDocument>), "writer"))

            // equivalence comparing
            .Add("new StonSemanticEntityEquivalenceComparer(document)", () => ExpectArgumentNull(() => new StonSemanticEntityEquivalenceComparer(null), "document"))
            .Add("new StonBindingKeyEquivalenceComparer(indexParameterComparer)", () => ExpectArgumentNull(() => new StonBindingKeyEquivalenceComparer(null), "indexParameterComparer"))

            // validation

            .Add("ValidateEntity(entity) 1", () => ExpectArgumentNull(() => ValidateEntity(null as IStonEntity), "entity"))
            .Add("ValidateEntity(entity) 2", () => ExpectArgumentNull(() => ValidateEntity(null as IStonValuedEntity), "entity"))
            .Add("ValidateEntity(entity) 3", () => ExpectArgumentNull(() => ValidateEntity(null as IStonSimpleEntity), "entity"))
            .Add("ValidateEntity(entity) 4", () => ExpectArgumentNull(() => ValidateEntity(null as IStonComplexEntity), "entity"))
            .Add("ValidateEntity(entity) 5", () => ExpectArgumentNull(() => ValidateEntity(null as IStonReferenceEntity), "entity"))

            .Add("ValidateGlobalIdentifier(globalIdentifier)", () => ExpectArgumentNull(() => ValidateGlobalIdentifier(null), "globalIdentifier"))

            .Add("ValidateType(type) 1", () => ExpectArgumentNull(() => ValidateType(null as IStonType), "type"))
            .Add("ValidateType(type) 2", () => ExpectArgumentNull(() => ValidateType(null as IStonNamedType), "type"))
            .Add("ValidateType(type) 3", () => ExpectArgumentNull(() => ValidateType(null as IStonCollectionType), "type"))
            .Add("ValidateType(type) 4", () => ExpectArgumentNull(() => ValidateType(null as IStonUnionType), "type"))

            .Add("ValidateSimpleValue(value)", () => ExpectArgumentNull(() => ValidateSimpleValue(null), "value"))

            .Add("ValidateConstruction(construction)", () => ExpectArgumentNull(() => ValidateConstruction(null), "construction"))
            .Add("ValidateMemberInit(memberInit)", () => ExpectArgumentNull(() => ValidateMemberInit(null), "memberInit"))
            .Add("ValidateBindingKey(bindingKey) 1", () => ExpectArgumentNull(() => ValidateBindingKey(null as IStonBindingKey), "bindingKey"))
            .Add("ValidateBindingKey(bindingKey) 2", () => ExpectArgumentNull(() => ValidateBindingKey(null as IStonBindingName), "bindingKey"))
            .Add("ValidateBindingKey(bindingKey) 3", () => ExpectArgumentNull(() => ValidateBindingKey(null as IStonBindingIndex), "bindingKey"))
            .Add("ValidateCollectionInit(collectionInit)", () => ExpectArgumentNull(() => ValidateCollectionInit(null), "collectionInit"))

            .Add("ValidateAddress(address)", () => ExpectArgumentNull(() => ValidateAddress(null), "address"))
            .Add("ValidateInitialContext(initialContext) 1", () => ExpectArgumentNull(() => ValidateInitialContext(null as IStonInitialContext), "initialContext"))
            .Add("ValidateInitialContext(initialContext) 2", () => ExpectArgumentNull(() => ValidateInitialContext(null as IStonAncestorInitialContext), "initialContext"))
            .Add("ValidateInitialContext(initialContext) 3", () => ExpectArgumentNull(() => ValidateInitialContext(null as IStonGlobalEntityInitialContext), "initialContext"))
            .Add("ValidatePathSegment(segment) 1", () => ExpectArgumentNull(() => ValidatePathSegment(null as IStonPathSegment), "segment"))
            .Add("ValidatePathSegment(segment) 2", () => ExpectArgumentNull(() => ValidatePathSegment(null as IStonAncestorPathSegment), "segment"))
            .Add("ValidatePathSegment(segment) 3", () => ExpectArgumentNull(() => ValidatePathSegment(null as IStonMemberPathSegment), "segment"))
            .Add("ValidatePathSegment(segment) 4", () => ExpectArgumentNull(() => ValidatePathSegment(null as IStonCollectionElementPathSegment), "segment"))

            // ironically, exceptions

            .Add("new StonImplementationException(elementType?,baseInterface,derivedInterfaces)", () => ExpectArgumentNull(() => new StonImplementationException(null, null, null as Type[]), "elementType"))
            .Add("new StonImplementationException(elementType,baseInterface?,derivedInterfaces)", () => ExpectArgumentNull(() => new StonImplementationException(typeof(object), null, null as Type[]), "baseInterface"))
            .Add("new StonImplementationException(elementType,baseInterface,derivedInterfaces?)", () => ExpectArgumentNull(() => new StonImplementationException(typeof(object), typeof(object), null as Type[]), "derivedInterfaces"))

            .Add("new StonDuplicateGlobalEntityException(firstEntity?,secondEntity)", () => ExpectArgumentNull(() => new StonDuplicateGlobalEntityException(null, null), "firstEntity"))
            .Add("new StonDuplicateGlobalEntityException(firstEntity,secondEntity?)", () => ExpectArgumentNull(() => new StonDuplicateGlobalEntityException(MakeActor <IStonEntity>(), null), "secondEntity"))
            .Add("new StonDuplicateGlobalEntityException(firstEntity?,secondEntity,message)", () => ExpectArgumentNull(() => new StonDuplicateGlobalEntityException(null, null, ""), "firstEntity"))
            .Add("new StonDuplicateGlobalEntityException(firstEntity,secondEntity?,message)", () => ExpectArgumentNull(() => new StonDuplicateGlobalEntityException(MakeActor <IStonEntity>(), null, ""), "secondEntity"))

            .Add("new StonCircularConstructionException(document?,constructionCycle)", () => ExpectArgumentNull(() => new StonCircularConstructionException(null, null), "document"))
            .Add("new StonCircularConstructionException(document,constructionCycle?)", () => ExpectArgumentNull <IStonDocument>((document) => new StonCircularConstructionException(document, null), "constructionCycle"))

            .Add("new StonExtensionTypeException(extensionType)", () => ExpectArgumentNull(() => new StonExtensionTypeException(null as IStonNamedType), "extensionType"))
            .Add("new StonExtensionTypeException(entity)", () => ExpectArgumentNull(() => new StonExtensionTypeException(null as IStonValuedEntity), "entity"))

            .Add("new StonExtensionTypeException(memberKey)", () => ExpectArgumentNull(() => new StonExtensionMemberException(null), "memberKey"))

            .Run();
        }
Example #28
0
        public void Test_NumberValues()
        {
            AggregateTester.New()

            // lots and lots of zeros
            .Add("0", () => ExpectParsedValue("0", StonDataType.Number, "0"))
            .Add("-0", () => ExpectParsedValue("-0", StonDataType.Number, "0"))
            .Add("+000.000", () => ExpectParsedValue("000.000", StonDataType.Number, "0"))
            .Add("+0e999", () => ExpectParsedValue("0e999", StonDataType.Number, "0"))
            .Add("000.000e999", () => ExpectParsedValue("000.000e999", StonDataType.Number, "0"))
            .Add("-0e-999", () => ExpectParsedValue("0e-999", StonDataType.Number, "0"))
            .Add("-000.000e-999", () => ExpectParsedValue("000.000e-999", StonDataType.Number, "0"))

            // syntactically valid non-zero numbers
            .Add("1", () => ExpectParsedValue("1", StonDataType.Number, "1e0"))
            .Add("1.000", () => ExpectParsedValue("1.000", StonDataType.Number, "1e0"))
            .Add("+0.001", () => ExpectParsedValue("0.001", StonDataType.Number, "1e-3"))
            .Add("-0.0000000000000005e16", () => ExpectParsedValue("-0.0000000000000005e16", StonDataType.Number, "-5e0"))
            .Add("+1000", () => ExpectParsedValue("1000", StonDataType.Number, "1e3"))
            .Add("+1 000 000", () => ExpectParsedValue("1 000 000", StonDataType.Number, "1e6"))
            .Add("0001", () => ExpectParsedValue("0001", StonDataType.Number, "1e0"))
            .Add("1.234e000", () => ExpectParsedValue("1.234e000", StonDataType.Number, "1234e-3"))
            .Add("+1.234e002", () => ExpectParsedValue("1.234e002", StonDataType.Number, "1234e-1"))
            .Add("+1.234e004", () => ExpectParsedValue("1.234e004", StonDataType.Number, "1234e1"))
            .Add("1.234e5678", () => ExpectParsedValue("1.234e5678", StonDataType.Number, "1234e5675"))
            .Add("1000e999...", () => ExpectParsedValue("1000e999999999999999999999999", StonDataType.Number, "1e1000000000000000000000002"))
            .Add("1000e-1000...", () => ExpectParsedValue("1000e-1000000000000000000000000", StonDataType.Number, "1e-999999999999999999999997"))
            .Add("-1000e999...", () => ExpectParsedValue("-1000e999999999999999999999999", StonDataType.Number, "-1e1000000000000000000000002"))
            .Add("-1000e-1000...", () => ExpectParsedValue("-1000e-1000000000000000000000000", StonDataType.Number, "-1e-999999999999999999999997"))
            .Add("-12.34e-1000...", () => ExpectParsedValue("-12.34e-1000000000000000000000000", StonDataType.Number, "-1234e-1000000000000000000000002"))
            .Add("+10100100010000", () => ExpectParsedValue("10100100010000", StonDataType.Number, "1010010001e4"))

            // syntactically invalid numbers
            .Add("-?", () => Expect.UnexpectedCharacter("-?", '?', StonChartype.Digit, 0, 1, 1))
            .Add("++12", () => Expect.UnexpectedCharacter("++12", '+', StonChartype.Digit, 0, 1, 1))
            .Add("-3.e4", () => Expect.UnexpectedCharacter("-3.e4", 'e', StonChartype.Digit, 0, 3, 3))
            .Add("-3.0e?", () => Expect.UnexpectedCharacter("-3.0e?", '?', StonChartype.Digit, 0, 5, 5))
            .Add("-3.0e-?", () => Expect.UnexpectedCharacter("-3.0e-?", '?', StonChartype.Digit, 0, 6, 6))
            .Add("-000.0000e?", () => Expect.UnexpectedCharacter("-000.0000e?", '?', StonChartype.Digit, 0, 10, 10))
            .Add("-000.0000e-?", () => Expect.UnexpectedCharacter("-000.0000e-?", '?', StonChartype.Digit, 0, 11, 11))

            // directly created valid numbers
            .Add("=0", () => ExpectValidValue(StonDataType.Number, "0", "0"))
            .Add("=123e0", () => ExpectValidValue(StonDataType.Number, "123e0", "123e0"))
            .Add("=-123e0", () => ExpectValidValue(StonDataType.Number, "-123e0", "-123e0"))
            .Add("=123e456", () => ExpectValidValue(StonDataType.Number, "123e456", "123e456"))
            .Add("=-123e456", () => ExpectValidValue(StonDataType.Number, "-123e456", "-123e456"))
            .Add("=123e-456", () => ExpectValidValue(StonDataType.Number, "123e-456", "123e-456"))
            .Add("=-123e-456", () => ExpectValidValue(StonDataType.Number, "-123e-456", "-123e-456"))
            .Add("=123e100", () => ExpectValidValue(StonDataType.Number, "123e100", "123e100"))
            .Add("=-123e100", () => ExpectValidValue(StonDataType.Number, "-123e100", "-123e100"))

            // directly created invalid numbers
            .Add("=-", () => ExpectInvalidValue(StonDataType.Number, "-", "A number simple value significand must have at least one digit."))
            .Add("=-0", () => ExpectInvalidValue(StonDataType.Number, "-0", "A number simple value significand cannot have leading zeros."))
            .Add("=e", () => ExpectInvalidValue(StonDataType.Number, "e", "A number simple value significand must be represented with decimal digits."))
            .Add("=-e", () => ExpectInvalidValue(StonDataType.Number, "-e", "A number simple value significand must be represented with decimal digits."))
            .Add("=?", () => ExpectInvalidValue(StonDataType.Number, "?", "A number simple value significand must be represented with decimal digits."))
            .Add("=-?", () => ExpectInvalidValue(StonDataType.Number, "-?", "A number simple value significand must be represented with decimal digits."))
            .Add("=00", () => ExpectInvalidValue(StonDataType.Number, "00", "A number simple value significand cannot have leading zeros."))

            .Add("=123E0", () => ExpectInvalidValue(StonDataType.Number, "123E0", "A number simple value cannot have an uppercase exponent sign."))
            .Add("=123?", () => ExpectInvalidValue(StonDataType.Number, "123?", "A number simple value significand must be represented with decimal digits."))
            .Add("=123", () => ExpectInvalidValue(StonDataType.Number, "123", "A non-zero number simple value must have an exponent."))
            .Add("=1000e0", () => ExpectInvalidValue(StonDataType.Number, "1000e0", "A number simple value significand cannot have trailing zeros."))

            .Add("=123e", () => ExpectInvalidValue(StonDataType.Number, "123e", "A number simple value exponent must have at least one digit."))
            .Add("=123e-", () => ExpectInvalidValue(StonDataType.Number, "123e-", "A number simple value exponent must have at least one digit."))
            .Add("=123e-0", () => ExpectInvalidValue(StonDataType.Number, "123e-0", "A number simple value exponent cannot have leading zeros."))
            .Add("=123e?", () => ExpectInvalidValue(StonDataType.Number, "123e?", "A number simple value exponent must be represented with decimal digits."))
            .Add("=123e-?", () => ExpectInvalidValue(StonDataType.Number, "123e-?", "A number simple value exponent must be represented with decimal digits."))
            .Add("=123e00", () => ExpectInvalidValue(StonDataType.Number, "123e00", "A number simple value exponent cannot have leading zeros."))
            .Add("=123e45?", () => ExpectInvalidValue(StonDataType.Number, "123e45?", "A number simple value exponent must be represented with decimal digits."))

            .Run();
        }
Example #29
0
        public void Test_StringValues()
        {
            AggregateTester.New()
            // basic parsed string literals
            .Add("\"Hello, world!\"", () => ExpectParsedValue("\"Hello, world!\"", StonDataType.Text, "Hello, world!"))
            .Add("'Hello, world!'", () => ExpectParsedValue("'Hello, world!'", StonDataType.Text, "Hello, world!"))
            .Add("`Hello, world!`", () => ExpectParsedValue("`Hello, world!`", StonDataType.Code, "Hello, world!"))
            .Add("\"Contractions aren't hard!\"", () => ExpectParsedValue("\"Contractions aren't hard!\"", StonDataType.Text, "Contractions aren't hard!"))
            .Add("\"Contractions aren\\'t hard!\"", () => ExpectParsedValue("\"Contractions aren\\'t hard!\"", StonDataType.Text, "Contractions aren't hard!"))
            .Add("'Contractions aren\\'t hard!'", () => ExpectParsedValue("'Contractions aren\\'t hard!'", StonDataType.Text, "Contractions aren't hard!"))
            .Add("`Contractions aren't hard!`", () => ExpectParsedValue("`Contractions aren't hard!`", StonDataType.Code, "Contractions aren't hard!"))
            .Add("\"I'm an \\\"annoyance\\\".\"", () => ExpectParsedValue("\"I'm an \\\"annoyance\\\".\"", StonDataType.Text, "I'm an \"annoyance\"."))
            .Add("'I\\'m an \"annoyance\".'", () => ExpectParsedValue("'I\\'m an \"annoyance\".'", StonDataType.Text, "I'm an \"annoyance\"."))
            .Add("`I'm an \"annoyance\".`", () => ExpectParsedValue("`I'm an \"annoyance\".`", StonDataType.Code, "I'm an \"annoyance\"."))

            // non-regular characters string literals
            .Add("\"私は「面倒」です。\"", () => ExpectParsedValue("\"私は「面倒」です。\"", StonDataType.Text, "私は「面倒」です。"))
            .Add("'私は「面倒」です。'", () => ExpectParsedValue("'私は「面倒」です。'", StonDataType.Text, "私は「面倒」です。"))
            .Add("`私は「面倒」です。`", () => ExpectParsedValue("`私は「面倒」です。`", StonDataType.Code, "私は「面倒」です。"))
            .Add("'\\u79C1\\u306F\\u300C\\u9762\\u5012\\u300D\\u3067\\u3059\\u3002'", () => ExpectParsedValue("'\\u79C1\\u306F\\u300C\\u9762\\u5012\\u300D\\u3067\\u3059\\u3002'", StonDataType.Text, "私は「面倒」です。"))
            .Add("'\\u79c1\\u306f\\u300c\\u9762\\u5012\\u300d\\u3067\\u3059\\u3002'", () => ExpectParsedValue("'\\u79c1\\u306f\\u300c\\u9762\\u5012\\u300d\\u3067\\u3059\\u3002'", StonDataType.Text, "私は「面倒」です。"))
            .Add("'\\'\\\"\\`\\\\\\/\\b\\f\\n\\r\\t\\0'", () => ExpectParsedValue("'\\'\\\"\\`\\\\\\/\\b\\f\\n\\r\\t\\0'", StonDataType.Text, "'\"`\\/\b\f\n\r\t\0"))

            // string literal chains
            .Add(">'a'", () => ExpectParsedValue(">'a'", StonDataType.Text, "a"))
            .Add(">'a'>'b'>'c'", () => ExpectParsedValue(">'a'>'b'>'c'", StonDataType.Text, "a\nb\nc"))
            .Add(">'a'+'b'+'c'", () => ExpectParsedValue(">'a'+'b'+'c'", StonDataType.Text, "abc"))
            .Add(">'a'+'b'>'c'", () => ExpectParsedValue(">'a'+'b'>'c'", StonDataType.Text, "ab\nc"))
            .Add(">'a'>\"b\">'c'", () => ExpectParsedValue(">'a'>\"b\">'c'", StonDataType.Text, "a\nb\nc"))
            .Add(">'a'+\"b\"+'c'", () => ExpectParsedValue(">'a'+\"b\"+'c'", StonDataType.Text, "abc"))
            .Add(">'a'+\"b\">'c'", () => ExpectParsedValue(">'a'+\"b\">'c'", StonDataType.Text, "ab\nc"))

            .Add(">`a`", () => ExpectParsedValue(">'a'", StonDataType.Text, "a"))
            .Add(">`a`>`b`>`c`", () => ExpectParsedValue(">`a`>`b`>`c`", StonDataType.Code, "a\nb\nc"))
            .Add(">`a`+`b`+`c`", () => ExpectParsedValue(">`a`+`b`+`c`", StonDataType.Code, "abc"))
            .Add(">`a`+`b`>`c`", () => ExpectParsedValue(">`a`+`b`>`c`", StonDataType.Code, "ab\nc"))

            // syntactically invalid strings
            .Add("'String that is unfi", () => Expect.UnexpectedCharacter("'String that is unfi", -1, StonChartype.None, 0, 20, 20, "Unexpected end of string encountered when parsing a STON string."))
            .Add("'String that is unfi\0nished.'", () => Expect.UnexpectedCharacter("'String that is unfi\0nished.'", 0, StonChartype.None, 0, 20, 20, "Unexpected end of string encountered when parsing a STON string."))
            .Add("'String with\nnewline'", () => Expect.UnexpectedCharacter("'String with\nnewline'", '\n', StonChartype.None, 0, 12, 12, "Unexpected control character #10. Control characters are not allowed in string literals."))
            .Add("'Escape \\?'", () => Expect.UnexpectedCharacter("'Escape \\?'", '?', StonChartype.None, 0, 9, 9, "Character '?' is not a part of recognized escape sequence."))
            .Add("'Escape \\", () => Expect.UnexpectedCharacter("'Escape \\", -1, StonChartype.None, 0, 9, 9, "Unexpected end of string encountered when parsing a STON string."))
            .Add("'\\u", () => Expect.UnexpectedCharacter("'\\u", -1, StonChartype.Base16, 0, 3, 3, "4 hexadecimal digits expected after Unicode escape code."))
            .Add("'\\u?", () => Expect.UnexpectedCharacter("'\\u?", '?', StonChartype.Base16, 0, 3, 3, "4 hexadecimal digits expected after Unicode escape code."))
            .Add("'\\uB", () => Expect.UnexpectedCharacter("'\\uB", -1, StonChartype.Base16, 0, 4, 4, "4 hexadecimal digits expected after Unicode escape code."))
            .Add("'\\uB?", () => Expect.UnexpectedCharacter("'\\uB?", '?', StonChartype.Base16, 0, 4, 4, "4 hexadecimal digits expected after Unicode escape code."))
            .Add("'\\uBE", () => Expect.UnexpectedCharacter("'\\uBE", -1, StonChartype.Base16, 0, 5, 5, "4 hexadecimal digits expected after Unicode escape code."))
            .Add("'\\uBEE", () => Expect.UnexpectedCharacter("'\\uBEE", -1, StonChartype.Base16, 0, 6, 6, "4 hexadecimal digits expected after Unicode escape code."))

            .Add(">(a)", () => Expect.UnexpectedCharacter(">(a)", '(', StonChartype.TextDelimiter | StonChartype.CodeDelimiter, 0, 1, 1))
            .Add(">'a'>`b`", () => Expect.UnexpectedCharacter(">'a'>`b`", '`', StonChartype.TextDelimiter, 0, 5, 5))
            .Add(">`a`>'b'", () => Expect.UnexpectedCharacter(">`a`>'b'", '\'', StonChartype.CodeDelimiter, 0, 5, 5))


            // canonical representation
            .Add("=text I'm `an \"annoyance\".", () => ExpectValidValue(StonDataType.Text, "I'm `an \"annoyance\".", "\"I'm `an \\\"annoyance\\\"\""))
            .Add("=code I'm `an \"annoyance\".", () => ExpectValidValue(StonDataType.Code, "I'm `an \"annoyance\".", "`I'm \\`an \"annoyance\"`"))
            .Add("=text 私は「面倒」です。", () => ExpectValidValue(StonDataType.Text, "私は「面倒」です。", "\"\\u79c1\\u306f\\u300c\\u9762\\u5012\\u300d\\u3067\\u3059\\u3002\""))
            .Add("=text '\"`\\/\b\f\n\r\t\0", () => ExpectValidValue(StonDataType.Text, " '\"`\\/\b\f\n\r\t\0\u007f", "\" '\\\"`\\\\/\\b\\f\\n\\r\\t\\u0000\\u007f\""))

            .Run();
        }