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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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"))); }
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 }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }