git/t/t0019-json-writer.sh
Jeff Hostetler 75459410ed json_writer: new routines to create JSON data
Add "struct json_writer" and a series of jw_ routines to compose JSON
data into a string buffer.  The resulting string may then be printed by
commands wanting to support a JSON-like output format.

The json_writer is limited to correctly formatting structured data for
output.  It does not attempt to build an object model of the JSON data.

We say "JSON-like" because we do not enforce the Unicode (usually UTF-8)
requirement on string fields.  Internally, Git does not necessarily have
Unicode/UTF-8 data for most fields, so it is currently unclear the best
way to enforce that requirement.  For example, on Linux pathnames can
contain arbitrary 8-bit character data, so a command like "status" would
not know how to encode the reported pathnames.  We may want to revisit
this (or double encode such strings) in the future.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: René Scharfe <l.s.r@web.de>
Helped-by: Wink Saville <wink@saville.com>
Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-16 13:55:39 -07:00

331 lines
5.8 KiB
Bash
Executable file

#!/bin/sh
test_description='test json-writer JSON generation'
. ./test-lib.sh
test_expect_success 'unit test of json-writer routines' '
test-tool json-writer -u
'
test_expect_success 'trivial object' '
cat >expect <<-\EOF &&
{}
EOF
cat >input <<-\EOF &&
object
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'trivial array' '
cat >expect <<-\EOF &&
[]
EOF
cat >input <<-\EOF &&
array
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'simple object' '
cat >expect <<-\EOF &&
{"a":"abc","b":42,"c":3.14,"d":true,"e":false,"f":null}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-double c 2 3.140
object-true d
object-false e
object-null f
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'simple array' '
cat >expect <<-\EOF &&
["abc",42,3.14,true,false,null]
EOF
cat >input <<-\EOF &&
array
array-string abc
array-int 42
array-double 2 3.140
array-true
array-false
array-null
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'escape quoting string' '
cat >expect <<-\EOF &&
{"a":"abc\\def"}
EOF
cat >input <<-\EOF &&
object
object-string a abc\def
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'escape quoting string 2' '
cat >expect <<-\EOF &&
{"a":"abc\"def"}
EOF
cat >input <<-\EOF &&
object
object-string a abc"def
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'nested inline object' '
cat >expect <<-\EOF &&
{"a":"abc","b":42,"sub1":{"c":3.14,"d":true,"sub2":{"e":false,"f":null}}}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-object sub1
object-double c 2 3.140
object-true d
object-object sub2
object-false e
object-null f
end
end
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'nested inline array' '
cat >expect <<-\EOF &&
["abc",42,[3.14,true,[false,null]]]
EOF
cat >input <<-\EOF &&
array
array-string abc
array-int 42
array-array
array-double 2 3.140
array-true
array-array
array-false
array-null
end
end
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'nested inline object and array' '
cat >expect <<-\EOF &&
{"a":"abc","b":42,"sub1":{"c":3.14,"d":true,"sub2":[false,null]}}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-object sub1
object-double c 2 3.140
object-true d
object-array sub2
array-false
array-null
end
end
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'nested inline object and array 2' '
cat >expect <<-\EOF &&
{"a":"abc","b":42,"sub1":{"c":3.14,"d":true,"sub2":[false,{"g":0,"h":1},null]}}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-object sub1
object-double c 2 3.140
object-true d
object-array sub2
array-false
array-object
object-int g 0
object-int h 1
end
array-null
end
end
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'pretty nested inline object and array 2' '
sed -e "s/^|//" >expect <<-\EOF &&
|{
| "a": "abc",
| "b": 42,
| "sub1": {
| "c": 3.14,
| "d": true,
| "sub2": [
| false,
| {
| "g": 0,
| "h": 1
| },
| null
| ]
| }
|}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-object sub1
object-double c 2 3.140
object-true d
object-array sub2
array-false
array-object
object-int g 0
object-int h 1
end
array-null
end
end
end
EOF
test-tool json-writer -p <input >actual &&
test_cmp expect actual
'
test_expect_success 'inline object with no members' '
cat >expect <<-\EOF &&
{"a":"abc","empty":{},"b":42}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-object empty
end
object-int b 42
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'inline array with no members' '
cat >expect <<-\EOF &&
{"a":"abc","empty":[],"b":42}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-array empty
end
object-int b 42
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_expect_success 'larger empty example' '
cat >expect <<-\EOF &&
{"a":"abc","empty":[{},{},{},[],{}],"b":42}
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-array empty
array-object
end
array-object
end
array-object
end
array-array
end
array-object
end
end
object-int b 42
end
EOF
test-tool json-writer <input >actual &&
test_cmp expect actual
'
test_lazy_prereq PERLJSON '
perl -MJSON -e "exit 0"
'
# As a sanity check, ask Perl to parse our generated JSON and recursively
# dump the resulting data in sorted order. Confirm that that matches our
# expectations.
test_expect_success PERLJSON 'parse JSON using Perl' '
cat >expect <<-\EOF &&
row[0].a abc
row[0].b 42
row[0].sub1 hash
row[0].sub1.c 3.14
row[0].sub1.d 1
row[0].sub1.sub2 array
row[0].sub1.sub2[0] 0
row[0].sub1.sub2[1] hash
row[0].sub1.sub2[1].g 0
row[0].sub1.sub2[1].h 1
row[0].sub1.sub2[2] null
EOF
cat >input <<-\EOF &&
object
object-string a abc
object-int b 42
object-object sub1
object-double c 2 3.140
object-true d
object-array sub2
array-false
array-object
object-int g 0
object-int h 1
end
array-null
end
end
end
EOF
test-tool json-writer <input >output.json &&
perl "$TEST_DIRECTORY"/t0019/parse_json.perl <output.json >actual &&
test_cmp expect actual
'
test_done