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)
+ }],
+ ][:])
+}
+