1 module vision.json.patch.operation.unittesting;
2 
3 import std.json : parseJSON;
4 import vision.json.patch.operation;
5 
6 unittest
7 {
8 	JsonItem a = parseJSON(`{"a":123,"b":"string","c":{"p1":1}}`);
9 	JsonItem b = parseJSON(`{"b":"string","a":123,"c":{"p1":1}}`);
10 	JsonItem c = parseJSON(`{"a":123,"b":"string","c":{"p1":2}}`);
11 	
12 	assert(a == b);
13 	assert(a != c);
14 }
15 
16 unittest 
17 {
18 	import std.stdio;
19 	
20 	auto source = parseJSON(`{
21 		"intProp": 123,
22 		"stringProp": "just a string",
23 		"nullProp": null,
24 		"floatProp": 123.45,
25 		"arrayProp": [
26 		    1,
27 		    "foo",
28 		    "bar",
29 		    {
30 		      "a": 1,
31 		      "b": "property b"
32 		    }		   
33 		],
34 		"objectProp": {
35 		    "name": "nested object",
36 		    "amount": 1,
37 		    "G": 6.674e-11
38 		}
39 	}`);
40 
41 	
42 	//writeln(source.toJSON);
43 	
44 	// toJsonString()
45 	assert(new TestOperation("/intProp", JsonItem(123)).toJsonString == `{"op":"test","path":"/intProp","value":123}`, DiffOperation.lastError);
46 	assert(new TestOperation("/stringProp", JsonItem("just a string")).toJsonString == `{"op":"test","path":"/stringProp","value":"just a string"}`, DiffOperation.lastError);
47 	assert(new TestOperation("/objectProp/name", JsonItem("nested object")).toJsonString == `{"op":"test","path":"/objectProp/name","value":"nested object"}`, DiffOperation.lastError);
48 	assert(new AddOperation("/objectProp/c", JsonItem(123)).toJsonString == `{"op":"add","path":"/objectProp/c","value":123}`, DiffOperation.lastError);
49 	assert(new AddOperation("/arrayProp/-", JsonItem("four")).toJsonString == `{"op":"add","path":"/arrayProp/-","value":"four"}`, DiffOperation.lastError);
50 	assert(new AddOperation("/a/b", parseJSON(`{"p1":"s1","p2":555}`)).toJsonString == `{"op":"add","path":"/a/b","value":{"p1":"s1","p2":555}}`, DiffOperation.lastError);
51 	assert(new RemoveOperation("/a/b").toJsonString == `{"op":"remove","path":"/a/b"}`, DiffOperation.lastError);
52 	assert(new ReplaceOperation("/foo/bar", JsonItem("abc")).toJsonString == `{"op":"replace","path":"/foo/bar","value":"abc"}`, DiffOperation.lastError);
53 	assert(new MoveOperation("/foo/bar", JsonPointer("/foo/fromhere")).toJsonString == `{"from":"/foo/fromhere","op":"move","path":"/foo/bar"}`, DiffOperation.lastError);
54 	assert(new CopyOperation("/foo/bar", JsonPointer("/foo/fromhere")).toJsonString == `{"from":"/foo/fromhere","op":"copy","path":"/foo/bar"}`, DiffOperation.lastError);
55 	
56 	// test applyTo() 
57 	assert(new TestOperation("/intProp", JsonItem(123)).applyTo(source), DiffOperation.lastError);
58 	assert(!new TestOperation("/intProp", JsonItem(1)).applyTo(source), DiffOperation.lastError);
59 	assert(new TestOperation("/stringProp", JsonItem("just a string")).applyTo(source), DiffOperation.lastError);
60 	assert(!new TestOperation("/stringProp", JsonItem("wrong string")).applyTo(source), DiffOperation.lastError);
61 	assert(new TestOperation("/objectProp/name", JsonItem("nested object")).applyTo(source), DiffOperation.lastError);
62 	
63 	// add applyTo()
64 	
65 	auto empty = parseJSON(`{}`);
66 	assert(new AddOperation("", source).applyTo(empty), DiffOperation.lastError);
67 	assert(empty == source);
68 
69 	assert(new AddOperation("/objectProp/c", JsonItem(123)).applyTo(source), DiffOperation.lastError);
70 	assert(new TestOperation("/objectProp/c", JsonItem(123)).applyTo(source), DiffOperation.lastError);
71 	
72 	assert(new AddOperation("/arrayProp/-", JsonItem("four")).applyTo(source), DiffOperation.lastError);
73 	assert(new TestOperation("/arrayProp/4", JsonItem("four")).applyTo(source), DiffOperation.lastError);
74 
75 	assert(!new AddOperation("/arrayProp/nonInteger", JsonItem(1)).applyTo(source));
76 	assert(!new AddOperation("/intProp/1", JsonItem(1)).applyTo(source));
77 
78 	assert(new AddOperation("/arrayProp/4", JsonItem("four again")).applyTo(source), DiffOperation.lastError);
79 	assert(new TestOperation("/arrayProp/4", JsonItem("four again")).applyTo(source), DiffOperation.lastError);
80 	assert(new TestOperation("/arrayProp/5", JsonItem("four")).applyTo(source), DiffOperation.lastError);
81 	assert(new AddOperation("/arrayProp/6", JsonItem("six")).applyTo(source), DiffOperation.lastError);
82 	assert(new TestOperation("/arrayProp/6", JsonItem("six")).applyTo(source), DiffOperation.lastError);
83 	assert(!new AddOperation("/arrayProp/8", JsonItem(0)).applyTo(source), DiffOperation.lastError);
84 
85 	assert(!new AddOperation("/nonExisting/prop", JsonItem("something")).applyTo(source), DiffOperation.lastError);
86 	assert(JsonPointer("/nonExisting").evaluate(source).isNull);
87 
88 	// remove applyTo()
89 	assert(new RemoveOperation("/arrayProp/4").applyTo(source), DiffOperation.lastError);
90 	assert(new TestOperation("/arrayProp/4", JsonItem("four")).applyTo(source), DiffOperation.lastError);
91 	assert(new TestOperation("/arrayProp/5", JsonItem("six")).applyTo(source), DiffOperation.lastError);
92 
93 	assert(!new RemoveOperation("/arrayProp/100").applyTo(source));
94 	assert(!new RemoveOperation("/arrayProp/nonInteger").applyTo(source));
95 	assert(!new RemoveOperation("/intProp/1").applyTo(source));
96 
97 	assert(new RemoveOperation("/objectProp/c").applyTo(source), DiffOperation.lastError);
98 	assert(JsonPointer("/objectProp/c").evaluate(source).isNull);
99 
100 	assert(!new RemoveOperation("/nonExisting").applyTo(source), DiffOperation.lastError);
101 
102 	auto simple = parseJSON(`{"intProp": 123}`);
103 	assert(new RemoveOperation("").applyTo(simple));
104 	assert(simple == RemoveOperation.emptyObject);
105 	
106 	assert(new ReplaceOperation("", source).applyTo(simple));
107 	assert(simple == source);
108 	
109 	simple = parseJSON(`[1,2,3,4,5]`);
110 	assert(new RemoveOperation("/0").applyTo(simple));
111 	
112 	
113 	assert(!new ReplaceOperation("/nonExisting", JsonItem(0)).applyTo(source));
114 	
115 	// copy applyTo()
116 	assert(new CopyOperation("/objectProp/string", "/stringProp").applyTo(source));
117 	assert(new TestOperation("/objectProp/string", JsonItem("just a string")).applyTo(source));
118 	
119 	assert(new CopyOperation("/arrayProp/2", "/stringProp").applyTo(source));
120 	assert(new TestOperation("/arrayProp/2", JsonItem("just a string")).applyTo(source));
121 
122 	assert(!new CopyOperation("/arrayProp/2", "/nonExisting").applyTo(source));
123 	
124 	// move applyTo()
125 	assert(new MoveOperation("/objectProp1", "/objectProp").applyTo(source), DiffOperation.lastError);
126 	assert(new TestOperation("/objectProp1/name", JsonItem("nested object")).applyTo(source));
127 	assert(JsonPointer("/objectProp").evaluate(source).isNull);
128 
129 	assert(!new MoveOperation("/objectProp", "/nonExisting").applyTo(source));
130 
131 	import std.exception: assertThrown;
132 
133 	foreach(s; [`{"op":"unknown", "path" : ""}`, `{"noop":"unknown", "path" : ""}`, `{"op": 1, "path" : ""}`, `["unknown", "path"]`, `{"op":"remove"}`])
134 	{
135 		auto op = parseJSON(s);
136 		assertThrown(op.toOperation);
137 	}
138 }
139