summaryrefslogtreecommitdiff
path: root/lib/json/test/parse.myr
blob: 0045fb744e0a4325288b9e9cc9456082178aa89e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use std
use json
use testr

const main = {
	strtest()
	filetest()
}

const strtest = {
	testr.run([
		[.name="null", .fn={ctx
			var j = std.try(json.parse("null"))
			match j
			| &(`json.Null):	std.put("ok\n")
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
		[.name="bool", .fn={ctx
			var j = std.try(json.parse("true"))
			match j
			| &(`json.Bool true):	std.put("ok\n")
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			j = std.try(json.parse("false"))
			match j
			| &(`json.Bool false):	std.put("ok\n")
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
		[.name="num", .fn={ctx
			var j = std.try(json.parse("123"))
			match j
			| &(`json.Num 123.0):	std.put("ok\n")
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
		[.name="str", .fn={ctx
			var j = std.try(json.parse("\"some str\""))
			match j
			| &(`json.Str "some str"):	std.put("ok\n")
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
		[.name="arr", .fn={ctx
			var j = std.try(json.parse("[\"some str\", 123, false]"))
			match j
			| &(`json.Arr a):
				match a[0]
				| &(`json.Str "some str"):	std.put("ok\n")
				| val:	testr.fail(ctx, "wrong value {}", val)
				;;
				match a[1]
				| &(`json.Num 123.0):	std.put("ok\n")
				| val:	testr.fail(ctx, "wrong value {}", val)
				;;
				match a[2]
				| &(`json.Bool false):	std.put("ok\n")
				| val:	testr.fail(ctx, "wrong value {}", val)
				;;
			| val:	testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
		[.name="obj", .fn={ctx
			var j = std.try(json.parse("{\"key\": 123, \"another\": \"foo\"}"))
			match j
			| &(`json.Obj a):
				match a[0]
				| ("key", &(`json.Num 123.0)):
					std.put("ok\n")
				| val:
					testr.fail(ctx, "wrong value {}", val)
				;;
				match a[1]
				| ("another", &(`json.Str "foo")):
					std.put("ok\n")
				| val:
					testr.fail(ctx, "wrong value {}", val)
				;;
			| val:
				testr.fail(ctx, "wrong value {}", val)
			;;
			json.free(j)
		}],
	][:])
}

const filetest = {
	var dir, data, path

	dir = std.try(std.diropen("test/inputs"))
	for f in std.byentry(dir)
		path = std.pathcat("test/inputs", f)
		data = std.try(std.slurp(path))
		/* 'n' indicates expected failure, 'y' indicates expected success, 'i' indicates implementation defined */
		match std.decode(f)
		| 'n':
			testr.run([
				[.name=f, .fn={ctx
					match json.parse(data)
					| `std.Err e:	/* ok */
					| `std.Ok r:	testr.fail(ctx, "succeeded in parsing malformed json: {}\n", r)
						std.die("hah")
					;;
				}]
			][:])

		| 'y':
			testr.run([
				[.name=f, .fn={ctx
					match json.parse(data)
					| `std.Err e:	testr.fail(ctx, "failed to parse json\n")
					| `std.Ok r:	json.free(r)
					;;
				}]
			][:])
		| '_':
			std.put("skip: {}\n", f)
		| 'i':
			std.put("ignoring implementation defined test {}\n", f)
		| wat:
			if !std.sleq(f, "LICENSE")
				std.fatal("unknown test {}: needs to start with y or n\n", f)
			;;
		;;
		std.slfree(data)
		std.slfree(path)
	;;
}