summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-10-08 22:00:49 -0700
committerOri Bernstein <ori@eigenstate.org>2016-10-08 22:00:49 -0700
commit5fe50d56c715b429483efd770df2b1bcdc7531ad (patch)
tree13bf911aa66156662c3488ef82fdaef2b877b942
parent8ff705e2485ef1aa6b95d038a4a38d0893e05471 (diff)
downloadmc-5fe50d56c715b429483efd770df2b1bcdc7531ad.tar.gz
Add tests, and fix up a few minor bugs.
-rw-r--r--lib/json/fmt.myr1
-rw-r--r--lib/json/parse.myr14
-rw-r--r--lib/json/test/parse.myr87
3 files changed, 99 insertions, 3 deletions
diff --git a/lib/json/fmt.myr b/lib/json/fmt.myr
index c158e3a..04867f2 100644
--- a/lib/json/fmt.myr
+++ b/lib/json/fmt.myr
@@ -22,6 +22,7 @@ const eltfmt = {sb, e, ind
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)
diff --git a/lib/json/parse.myr b/lib/json/parse.myr
index eda211c..f7fad7e 100644
--- a/lib/json/parse.myr
+++ b/lib/json/parse.myr
@@ -51,11 +51,11 @@ const parseelt = {p
| '[': -> 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)
@@ -241,6 +241,14 @@ const jsonstr = {p
-> `std.Err err
}
+const matchprefix = {p, pfx
+ if std.hasprefix(p.str[p.idx:], pfx)
+ p.idx += pfx.len
+ -> true
+ ;;
+ -> false
+}
+
const takespace = {p
while true
match (p.str[p.idx] : char)
diff --git a/lib/json/test/parse.myr b/lib/json/test/parse.myr
new file mode 100644
index 0000000..77d747f
--- /dev/null
+++ b/lib/json/test/parse.myr
@@ -0,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)
+ }],
+ ][:])
+}
+