shithub: mc

Download patch

ref: 5fe50d56c715b429483efd770df2b1bcdc7531ad
parent: 8ff705e2485ef1aa6b95d038a4a38d0893e05471
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Oct 8 18:00:49 EDT 2016

Add tests, and fix up a few minor bugs.

--- a/lib/json/fmt.myr
+++ b/lib/json/fmt.myr
@@ -22,6 +22,7 @@
 	match e
 	| &(`Null):	std.sbfmt(sb, "null")
 	| &(`Bool b):	std.sbfmt(sb, "{}", b)
+	| &(`Num n):	std.sbfmt(sb, "{}", n)
 	| &(`Str s):	jstrfmt(sb, s)
 	| &(`Arr a):	arrfmt(sb, a, ind)
 	| &(`Obj o):	objfmt(sb, o, ind)
--- a/lib/json/parse.myr
+++ b/lib/json/parse.myr
@@ -51,11 +51,11 @@
 	| '[':	-> parsearr(p)
 	| '"':	-> parsestr(p)
 	| chr:
-		if std.hasprefix(p.str[p.idx:], "false")
+		if matchprefix(p, "false")
 			-> `std.Ok std.mk(`Bool false)
-		elif std.hasprefix(p.str[p.idx:], "true")
+		elif matchprefix(p, "true")
 			-> `std.Ok std.mk(`Bool true)
-		elif std.hasprefix(p.str[p.idx:], "null")
+		elif matchprefix(p, "null")
 			-> `std.Ok std.mk(`Null)
 		elif std.isdigit(peekc(p)) || peekc(p) == '-'
 			match parsenum(p)
@@ -239,6 +239,14 @@
 :error
 	std.sbfree(sb)
 	-> `std.Err err
+}
+
+const matchprefix = {p, pfx
+	if std.hasprefix(p.str[p.idx:], pfx)
+		p.idx += pfx.len
+		-> true
+	;;
+	-> false
 }
 
 const takespace = {p
--- /dev/null
+++ b/lib/json/test/parse.myr
@@ -1,0 +1,87 @@
+use std
+use json
+use testr
+
+const main = {
+	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)
+		}],
+	][:])
+}
+