From 080aeea015be41c10932b3cd594eadd1c112bc4a Mon Sep 17 00:00:00 2001 From: Daylon Wilkins Date: Sat, 15 Feb 2020 21:39:00 -0800 Subject: [PATCH] TypeInfo tests --- bats/back-compat.bats | 162 +++ .../testdata/20200113/.dolt/config.json | 1 + .../noms/09hv7tllti9b3hfi7u5m3e7lpbne390a | Bin 0 -> 159 bytes .../noms/0kl39j0i7gljemj93loojdhdbsj9lb36 | Bin 0 -> 284 bytes .../noms/1nrr0bod1960bccqc6c2med68hod5gc7 | Bin 0 -> 330 bytes .../noms/1rnurg4no9s6s23mdq8vvfmj0cik47db | Bin 0 -> 211 bytes .../noms/3dsltc9vis2m6o89bv0dh482pfme30ss | Bin 0 -> 262 bytes .../noms/4bujnjuatdli0klda7ucot0tl836jujt | Bin 0 -> 57 bytes .../noms/5im08tb1mu140r7kvtrd04u8ub5qk607 | Bin 0 -> 832 bytes .../noms/6739m2utlhl1k98f4o2fqmgtm12ino4t | Bin 0 -> 211 bytes .../noms/6oc2i2n9ln25n8go78dalvo3e9er9mg3 | Bin 0 -> 122 bytes .../noms/7er6962c841ghn8j0a357ujde9daq3mu | Bin 0 -> 716 bytes .../noms/7vu480853r3b0hitt89l7gc3r854fb53 | Bin 0 -> 262 bytes .../noms/89knkh4sejb7tf05gqq01osftlbsmdq1 | Bin 0 -> 1665 bytes .../noms/9guvpb6l55h1t9aqaa9b7qnp1dnnelkd | Bin 0 -> 262 bytes .../noms/9ibrf56gr6gsgr7cpnda4au9o0vd0412 | Bin 0 -> 650 bytes bats/helper/testdata/20200113/.dolt/noms/LOCK | 0 .../noms/a8hqijvam2c6r9qvbffsdj5r55bis0mn | Bin 0 -> 668 bytes .../noms/a9307merr53dd71vj459m7qo6rk435na | Bin 0 -> 262 bytes .../noms/ag7kv5tuc4jvovmas7r5kel32dd94g86 | Bin 0 -> 262 bytes .../noms/c8a3b64elue3121ng0rgeagcnf48fbat | Bin 0 -> 229 bytes .../noms/c8dirve58o6npl3aufbupn3c2pt55el4 | Bin 0 -> 1069 bytes .../noms/ca9rtjbjd7n5pkodo3rsl6bon0s8qe4j | Bin 0 -> 262 bytes .../noms/csopsqdj2urggh85gbsfth4c9lf4r8vb | Bin 0 -> 262 bytes .../noms/di7sdosugcarnn353e8ldbnlts9v42s5 | Bin 0 -> 192 bytes .../noms/eiit9a47igil0id02vhgpq4g72ga3dha | Bin 0 -> 229 bytes .../noms/es7vlqed0665gq9es3ns2uqeh75bkerc | Bin 0 -> 881 bytes .../noms/fkes7bk2bl0p9cvfgk3dd7uf6p4cqcm1 | Bin 0 -> 229 bytes .../noms/frc0ef452fhh97o534e7lol2b427lk56 | Bin 0 -> 262 bytes .../noms/g2slg3mhtfb5m2tk00t8mor5lkboqj2m | Bin 0 -> 262 bytes .../noms/glc2mu652o0pt893a79j30tc6kgvk453 | Bin 0 -> 211 bytes .../noms/hgsmoadjsib12ml6e05or4q5urv9lt7l | Bin 0 -> 1081 bytes .../noms/ie2tcnurro57vl8urvucbjdrmmf9bo0h | Bin 0 -> 249 bytes .../noms/iellg8am40vu2tf61hbe7i0anhm76gtv | Bin 0 -> 279 bytes .../noms/jji5lv8nq265dpk6r11ug3gb6ih81hdr | Bin 0 -> 262 bytes .../noms/ju51cbttj99itbsbk2svu7sij2tu4rhl | Bin 0 -> 1554 bytes .../noms/k3ksuke2vcb2hgatpdqbhildb8raab5p | Bin 0 -> 262 bytes .../noms/kmjfnt24t2vf8e58u3r5insr7tfohm2e | Bin 0 -> 211 bytes .../noms/m297l94np7ub1bp8irhpf3eta6bpegr8 | Bin 0 -> 923 bytes .../noms/m3sn7rmfc0lbis3codosl1k46hpv0kod | Bin 0 -> 457 bytes .../testdata/20200113/.dolt/noms/manifest | 1 + .../noms/miv7sdaoglrgfs2rgafm77kr6h9cbgvn | Bin 0 -> 211 bytes .../noms/ml7hl70ar993tc32gla4ttjar0ogka86 | Bin 0 -> 284 bytes .../noms/naromh9oel8c6dmmg6lvg61ot3gvomkv | Bin 0 -> 262 bytes .../noms/oarahke38ufh3tmnfpafuvb51dfbhgmh | Bin 0 -> 783 bytes .../noms/og4gt15c913id9e4iv7bcobjkn6aqn8d | Bin 0 -> 229 bytes .../noms/ojdo9hafo3mvlko0cefqcom7os26utln | Bin 0 -> 211 bytes .../noms/os1po1dclurjkflegl02usl2r8rkg2cq | Bin 0 -> 262 bytes .../noms/q5eq2e7gn1osgqg6bdqctgi7o7lapsik | Bin 0 -> 229 bytes .../noms/qqc5268agbqc0nqdud6gn7m202teffnm | Bin 0 -> 1069 bytes .../noms/rcksm0pvt2fop4deb2tf881mo0vj4ih8 | Bin 0 -> 229 bytes .../noms/rrbqpqt3l59s17rbva7pjrqhitbe4cc2 | Bin 0 -> 262 bytes .../noms/s69lvejsvg9so3l2nsquavmbai4dmu03 | Bin 0 -> 934 bytes .../noms/srlc19tj78ldn4hbb8duso90i1vugc59 | Bin 0 -> 249 bytes .../noms/tmie2h7f80pblg0ojfk0v50qu8s97mpa | Bin 0 -> 309 bytes .../noms/u62g6ma6evirqjb11i0up0p1hppb50ou | Bin 0 -> 284 bytes .../noms/ug6l7o53ntp50f252u65cj96om411v14 | Bin 0 -> 926 bytes .../testdata/20200113/.dolt/repo_state.json | 8 + bats/helper/testdata/20200113/README.md | 75 ++ bats/helper/testdata/README.md | 34 + bats/types.bats | 995 ++++++++++++++++++ .../doltcore/schema/typeinfo/bit_test.go | 253 +++++ .../doltcore/schema/typeinfo/bool_test.go | 180 ++++ .../doltcore/schema/typeinfo/common_test.go | 39 + .../doltcore/schema/typeinfo/datetime_test.go | 264 +++++ .../doltcore/schema/typeinfo/decimal_test.go | 50 + .../doltcore/schema/typeinfo/enum_test.go | 49 + .../doltcore/schema/typeinfo/float_test.go | 230 ++++ .../schema/typeinfo/inlineblob_test.go | 161 +++ .../doltcore/schema/typeinfo/int_test.go | 277 +++++ .../doltcore/schema/typeinfo/set_test.go | 43 + .../doltcore/schema/typeinfo/time_test.go | 17 + .../doltcore/schema/typeinfo/typeinfo_test.go | 381 +++++++ .../doltcore/schema/typeinfo/uint_test.go | 271 +++++ .../doltcore/schema/typeinfo/uuid_test.go | 204 ++++ .../schema/typeinfo/varbinary_test.go | 48 + .../schema/typeinfo/varstring_test.go | 289 +++++ .../doltcore/schema/typeinfo/year_test.go | 210 ++++ 78 files changed, 4242 insertions(+) create mode 100644 bats/back-compat.bats create mode 100644 bats/helper/testdata/20200113/.dolt/config.json create mode 100644 bats/helper/testdata/20200113/.dolt/noms/09hv7tllti9b3hfi7u5m3e7lpbne390a create mode 100644 bats/helper/testdata/20200113/.dolt/noms/0kl39j0i7gljemj93loojdhdbsj9lb36 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/1nrr0bod1960bccqc6c2med68hod5gc7 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/1rnurg4no9s6s23mdq8vvfmj0cik47db create mode 100644 bats/helper/testdata/20200113/.dolt/noms/3dsltc9vis2m6o89bv0dh482pfme30ss create mode 100644 bats/helper/testdata/20200113/.dolt/noms/4bujnjuatdli0klda7ucot0tl836jujt create mode 100644 bats/helper/testdata/20200113/.dolt/noms/5im08tb1mu140r7kvtrd04u8ub5qk607 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/6739m2utlhl1k98f4o2fqmgtm12ino4t create mode 100644 bats/helper/testdata/20200113/.dolt/noms/6oc2i2n9ln25n8go78dalvo3e9er9mg3 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/7er6962c841ghn8j0a357ujde9daq3mu create mode 100644 bats/helper/testdata/20200113/.dolt/noms/7vu480853r3b0hitt89l7gc3r854fb53 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/89knkh4sejb7tf05gqq01osftlbsmdq1 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/9guvpb6l55h1t9aqaa9b7qnp1dnnelkd create mode 100644 bats/helper/testdata/20200113/.dolt/noms/9ibrf56gr6gsgr7cpnda4au9o0vd0412 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/LOCK create mode 100644 bats/helper/testdata/20200113/.dolt/noms/a8hqijvam2c6r9qvbffsdj5r55bis0mn create mode 100644 bats/helper/testdata/20200113/.dolt/noms/a9307merr53dd71vj459m7qo6rk435na create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ag7kv5tuc4jvovmas7r5kel32dd94g86 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/c8a3b64elue3121ng0rgeagcnf48fbat create mode 100644 bats/helper/testdata/20200113/.dolt/noms/c8dirve58o6npl3aufbupn3c2pt55el4 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ca9rtjbjd7n5pkodo3rsl6bon0s8qe4j create mode 100644 bats/helper/testdata/20200113/.dolt/noms/csopsqdj2urggh85gbsfth4c9lf4r8vb create mode 100644 bats/helper/testdata/20200113/.dolt/noms/di7sdosugcarnn353e8ldbnlts9v42s5 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/eiit9a47igil0id02vhgpq4g72ga3dha create mode 100644 bats/helper/testdata/20200113/.dolt/noms/es7vlqed0665gq9es3ns2uqeh75bkerc create mode 100644 bats/helper/testdata/20200113/.dolt/noms/fkes7bk2bl0p9cvfgk3dd7uf6p4cqcm1 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/frc0ef452fhh97o534e7lol2b427lk56 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/g2slg3mhtfb5m2tk00t8mor5lkboqj2m create mode 100644 bats/helper/testdata/20200113/.dolt/noms/glc2mu652o0pt893a79j30tc6kgvk453 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/hgsmoadjsib12ml6e05or4q5urv9lt7l create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ie2tcnurro57vl8urvucbjdrmmf9bo0h create mode 100644 bats/helper/testdata/20200113/.dolt/noms/iellg8am40vu2tf61hbe7i0anhm76gtv create mode 100644 bats/helper/testdata/20200113/.dolt/noms/jji5lv8nq265dpk6r11ug3gb6ih81hdr create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ju51cbttj99itbsbk2svu7sij2tu4rhl create mode 100644 bats/helper/testdata/20200113/.dolt/noms/k3ksuke2vcb2hgatpdqbhildb8raab5p create mode 100644 bats/helper/testdata/20200113/.dolt/noms/kmjfnt24t2vf8e58u3r5insr7tfohm2e create mode 100644 bats/helper/testdata/20200113/.dolt/noms/m297l94np7ub1bp8irhpf3eta6bpegr8 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/m3sn7rmfc0lbis3codosl1k46hpv0kod create mode 100644 bats/helper/testdata/20200113/.dolt/noms/manifest create mode 100644 bats/helper/testdata/20200113/.dolt/noms/miv7sdaoglrgfs2rgafm77kr6h9cbgvn create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ml7hl70ar993tc32gla4ttjar0ogka86 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/naromh9oel8c6dmmg6lvg61ot3gvomkv create mode 100644 bats/helper/testdata/20200113/.dolt/noms/oarahke38ufh3tmnfpafuvb51dfbhgmh create mode 100644 bats/helper/testdata/20200113/.dolt/noms/og4gt15c913id9e4iv7bcobjkn6aqn8d create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ojdo9hafo3mvlko0cefqcom7os26utln create mode 100644 bats/helper/testdata/20200113/.dolt/noms/os1po1dclurjkflegl02usl2r8rkg2cq create mode 100644 bats/helper/testdata/20200113/.dolt/noms/q5eq2e7gn1osgqg6bdqctgi7o7lapsik create mode 100644 bats/helper/testdata/20200113/.dolt/noms/qqc5268agbqc0nqdud6gn7m202teffnm create mode 100644 bats/helper/testdata/20200113/.dolt/noms/rcksm0pvt2fop4deb2tf881mo0vj4ih8 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/rrbqpqt3l59s17rbva7pjrqhitbe4cc2 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/s69lvejsvg9so3l2nsquavmbai4dmu03 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/srlc19tj78ldn4hbb8duso90i1vugc59 create mode 100644 bats/helper/testdata/20200113/.dolt/noms/tmie2h7f80pblg0ojfk0v50qu8s97mpa create mode 100644 bats/helper/testdata/20200113/.dolt/noms/u62g6ma6evirqjb11i0up0p1hppb50ou create mode 100644 bats/helper/testdata/20200113/.dolt/noms/ug6l7o53ntp50f252u65cj96om411v14 create mode 100644 bats/helper/testdata/20200113/.dolt/repo_state.json create mode 100644 bats/helper/testdata/20200113/README.md create mode 100644 bats/helper/testdata/README.md create mode 100644 bats/types.bats create mode 100644 go/libraries/doltcore/schema/typeinfo/bit_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/bool_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/common_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/datetime_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/decimal_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/enum_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/float_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/inlineblob_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/int_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/set_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/time_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/typeinfo_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/uint_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/uuid_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/varbinary_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/varstring_test.go create mode 100644 go/libraries/doltcore/schema/typeinfo/year_test.go diff --git a/bats/back-compat.bats b/bats/back-compat.bats new file mode 100644 index 0000000000..5fe416dcb7 --- /dev/null +++ b/bats/back-compat.bats @@ -0,0 +1,162 @@ +#!/usr/bin/env bats +load $BATS_TEST_DIRNAME/helper/common.bash + +setup() { + setup_common + cp -a $BATS_TEST_DIRNAME/helper/testdata/. ./ +} + +teardown() { + teardown_common +} + +@test "back-compat: data check" { + for testdir in */; do + cd "$testdir" + run dolt status + [ "$status" -eq "0" ] + run dolt branch + [ "$status" -eq "0" ] + [[ "$output" =~ "master" ]] || false + [[ "$output" =~ "conflict" ]] || false + [[ "$output" =~ "newcolumn" ]] || false + run dolt schema show + [ "$status" -eq "0" ] + [[ "$output" =~ "\`pk\` BIGINT NOT NULL COMMENT 'tag:0'" ]] || false + [[ "$output" =~ "\`a\` LONGTEXT COMMENT 'tag:694'" ]] || false + [[ "$output" =~ "\`b\` DATETIME COMMENT 'tag:2902'" ]] || false + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[3]}" =~ " 1 " ]] || false + [[ "${lines[3]}" =~ " data " ]] || false + [[ "${lines[3]}" =~ " 2020-01-13 20:45:18.53558 " ]] || false + dolt checkout conflict + run dolt schema show + [ "$status" -eq "0" ] + [[ "$output" =~ "\`pk\` BIGINT NOT NULL COMMENT 'tag:0'" ]] || false + [[ "$output" =~ "\`a\` LONGTEXT COMMENT 'tag:694'" ]] || false + [[ "$output" =~ "\`b\` DATETIME COMMENT 'tag:2902'" ]] || false + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[3]}" =~ " 1 " ]] || false + [[ "${lines[3]}" =~ " data " ]] || false + [[ "${lines[3]}" =~ " 2020-01-13 20:45:18.53558 " ]] || false + [[ "${lines[4]}" =~ " 2 " ]] || false + [[ "${lines[4]}" =~ " something " ]] || false + [[ "${lines[4]}" =~ " 2020-01-14 20:48:37.13061 " ]] || false + dolt checkout newcolumn + run dolt schema show + [ "$status" -eq "0" ] + [[ "$output" =~ "\`pk\` BIGINT NOT NULL COMMENT 'tag:0'" ]] || false + [[ "$output" =~ "\`a\` LONGTEXT COMMENT 'tag:694'" ]] || false + [[ "$output" =~ "\`b\` DATETIME COMMENT 'tag:2902'" ]] || false + [[ "$output" =~ "\`c\` BIGINT UNSIGNED COMMENT 'tag:4657'" ]] || false + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[3]}" =~ " 1 " ]] || false + [[ "${lines[3]}" =~ " data " ]] || false + [[ "${lines[3]}" =~ " 2020-01-13 20:45:18.53558 " ]] || false + [[ "${lines[3]}" =~ " 2133" ]] || false + [[ "${lines[4]}" =~ " 2 " ]] || false + [[ "${lines[4]}" =~ " something " ]] || false + [[ "${lines[4]}" =~ " 2020-01-13 20:48:37.13061 " ]] || false + [[ "${lines[4]}" =~ " 1132020" ]] || false + cd .. + done +} + +@test "back-compat: table operations" { + for testdir in */; do + cd "$testdir" + run dolt table cp abc copy + [ "$status" -eq "0" ] + run dolt table mv abc move + [ "$status" -eq "0" ] + run dolt ls + [ "$status" -eq "0" ] + [[ "$output" =~ "copy" ]] || false + [[ "$output" =~ "move" ]] || false + cd .. + done +} + +@test "back-compat: adding commits" { + for testdir in */; do + cd "$testdir" + run dolt sql -q "insert into abc values (2, 'text', '2020-01-15 20:49:22.28427')" + [ "$status" -eq "0" ] + run dolt add . + [ "$status" -eq "0" ] + run dolt commit -m "Add value during test" + [ "$status" -eq "0" ] + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[4]}" =~ " 2 " ]] || false + [[ "${lines[4]}" =~ " text " ]] || false + [[ "${lines[4]}" =~ " 2020-01-15 20:49:22.28427 " ]] || false + dolt checkout newcolumn + dolt checkout -b testaddcommit + run dolt sql -q "insert into abc values (3, 'text', '2020-01-15 20:49:22.28427', 9241)" + [ "$status" -eq "0" ] + run dolt add . + [ "$status" -eq "0" ] + run dolt commit -m "Add value during test" + [ "$status" -eq "0" ] + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[5]}" =~ " 3 " ]] || false + [[ "${lines[5]}" =~ " text " ]] || false + [[ "${lines[5]}" =~ " 2020-01-15 20:49:22.28427 " ]] || false + [[ "${lines[5]}" =~ " 9241 " ]] || false + cd .. + done +} + +@test "back-compat: merging" { + for testdir in */; do + cd "$testdir" + run dolt merge newcolumn + [ "$status" -eq "0" ] + [[ "$output" =~ "Fast-forward" ]] || false + cd .. + done +} + +@test "back-compat: resolving conflicts" { + for testdir in */; do + cd "$testdir" + dolt checkout conflict + run dolt merge newcolumn + [ "$status" -eq "0" ] + [[ "$output" =~ "CONFLICT" ]] || false + run dolt conflicts cat abc + [ "$status" -eq "0" ] + [[ "${lines[3]}" =~ " ours " ]] || false + [[ "${lines[3]}" =~ " 2 " ]] || false + [[ "${lines[3]}" =~ " something " ]] || false + [[ "${lines[3]}" =~ " 2020-01-14 20:48:37.13061 " ]] || false + [[ "${lines[3]}" =~ " " ]] || false + [[ "${lines[4]}" =~ " theirs " ]] || false + [[ "${lines[4]}" =~ " 2 " ]] || false + [[ "${lines[4]}" =~ " something " ]] || false + [[ "${lines[4]}" =~ " 2020-01-13 20:48:37.13061 " ]] || false + [[ "${lines[4]}" =~ " 1132020 " ]] || false + run dolt conflicts resolve --theirs abc + [ "$status" -eq "0" ] + run dolt add . + [ "$status" -eq "0" ] + run dolt commit -m "Merged newcolumn into conflict" + [ "$status" -eq "0" ] + run dolt sql -q "select * from abc order by pk asc" + [ "$status" -eq "0" ] + [[ "${lines[3]}" =~ " 1 " ]] || false + [[ "${lines[3]}" =~ " data " ]] || false + [[ "${lines[3]}" =~ " 2020-01-13 20:45:18.53558 " ]] || false + [[ "${lines[3]}" =~ " 2133" ]] || false + [[ "${lines[4]}" =~ " 2 " ]] || false + [[ "${lines[4]}" =~ " something " ]] || false + [[ "${lines[4]}" =~ " 2020-01-13 20:48:37.13061 " ]] || false + [[ "${lines[4]}" =~ " 1132020" ]] || false + cd .. + done +} diff --git a/bats/helper/testdata/20200113/.dolt/config.json b/bats/helper/testdata/20200113/.dolt/config.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/bats/helper/testdata/20200113/.dolt/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/bats/helper/testdata/20200113/.dolt/noms/09hv7tllti9b3hfi7u5m3e7lpbne390a b/bats/helper/testdata/20200113/.dolt/noms/09hv7tllti9b3hfi7u5m3e7lpbne390a new file mode 100644 index 0000000000000000000000000000000000000000..f8cb6d366e7dbc29458f3d13dcfcf52d8447c84e GIT binary patch literal 159 zcmZo;Jix}l%p_ctnpUizk(!uNte>2pmzI;6T*7|3&3+lzWYd**8W?jn1>U>bG4HQC z3k#E=td2--VsS}oQJfY7g9xkEl*~LJCoeHaKe;G1u_Tqf`*G^6DVeU0CHBYj|D8?C zFAd9>$ig@w@5R?&$wpNSi!9R_ARvGF#+NHv*7SESp63+-6k>#mxBcIG$jrnz$;{Buz%b2{ zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#EotX554YI$;gPHAo)yPSQH<=l@q|Fir#ytvrEY=-yzy`OyH{;_ Zr0c#zPyPdi7@^`{{%^f;NG17Q004a`YghmP literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/1nrr0bod1960bccqc6c2med68hod5gc7 b/bats/helper/testdata/20200113/.dolt/noms/1nrr0bod1960bccqc6c2med68hod5gc7 new file mode 100644 index 0000000000000000000000000000000000000000..dfb3629497b1f2fe483a0fb647fd7a15b9341a15 GIT binary patch literal 330 zcmX@ZXv4|ooS&PUS;EYcn_7~{$-&4Lk&;-F$i|YATAa)z<(ZdRl9`y3S(U25C|;pZ zlvo?Wu~A}Dnvs#YsZp|_nMIPRv2m)oMOvywl7XdBYFcs{ zyC(mHB0EF5>FcboS?v0s;I6l;y_1EBNw6q2tyn)JH8G`FKR2S{Kvvk zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+Z}_lzgc;ai$M%1#0VAt@_*}%Ln_Jd0sw_# BU8Vp4 literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/4bujnjuatdli0klda7ucot0tl836jujt b/bats/helper/testdata/20200113/.dolt/noms/4bujnjuatdli0klda7ucot0tl836jujt new file mode 100644 index 0000000000000000000000000000000000000000..c41b419f7c20cf86bd1a0030dd7abbbd06e7ef12 GIT binary patch literal 57 zcmZSPU}Ip=+7fK=!u{H&Tf*+M7$AT%eP#FypGmJ@6s*v61`07k#hL$ay>Un-`CR}2 D-mnpz literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/5im08tb1mu140r7kvtrd04u8ub5qk607 b/bats/helper/testdata/20200113/.dolt/noms/5im08tb1mu140r7kvtrd04u8ub5qk607 new file mode 100644 index 0000000000000000000000000000000000000000..5dd0d916923eeb0cdd884d3c2a23be14d91e99a0 GIT binary patch literal 832 zcmY$N!N$NS#3aDL&m_bmu#J_8B_**WQQ(@G2qOan1K-tkXYa|s@lE*upWoin^8w?B zZJewniAg!BOe{tD<;CpFUIwQ51{NHB|4unSp5vg~o!iVV6XxgpskGT$@w{@xp~E`oV>1i z$@wX%Db8R4R(_yFd~$wXaY<2PW?o4#Z)S0PL1Ix!e12MdK{iWvW?l+QUSe)4b4g-4 zE2kh_GfV>$zoczNd`V?NDjQH+Vs0@L8xI2y(1Q$2Odx*(0i%F!anljz3!FSD`8g%= zDM|4~`S~S`Y+&COvjG({CnhDcU-7^9?#;6TULl{_922G;;o_wxYdKk2RXZR7g6v)7 za9{`dlTj)Lmp54j50LChL0dsX7Ld`8OosJh2 zGl+ieno`~VkGI^t=q7^%6EL=zm<0aaU;rY&8w~B&RtC*x{4k4+ftg7|S3fPMv^YcG zFwNL3HObV{(%3L1Ejh_3G1VZ=(!|U%H8I)HEXgdDU6X%8k)5I3^mW$PEOz}*aM#<_ z-pRtmBnXW9V*QNN#FS$F+{EIN)FSr7g0DAe-|Eu+sqx3$Ag?Upaja4(3p0}lSS2ui zQ;YHvbM%voQWHy3*}EU7-kOr>>R4ibJpbR>wEWVrjEO9aa^FN-!%xoM;a0N61{izH zu!IPT$_u~44X%r41p}E(u=oP9K@qJB#1DZ?ZXmrFIng4=r>>{?``wfMJ#M-k$^NVF6+wU{3qL^~NEUo>rTB4zmg+ZdJSz?NjS&B(&im92QnVE^HaiW<;N@_|X zyC(mHB0EF5>FcboS?v0s;I6l;y_1EBNw6q2tyn)JH8G`FKR2Ebw`q0K{JZIKDc+Q#a%&h5C zk+6jc6=_J3QV)`^(G4;%DM~_%pexl&4?P4@5ZgnzHa-MBG<drq{TFeS;eSmrYyIw%A+S_;$X{0B_KEGoWfvJL9-a)(YEQg9=Mp<;Vp&B+9x$UB*3Z ziIod2ri<;lPLq1NUlO>cw5g}U$8n#mMatrl1_^~K$(L!o@-sR`W|x#J(j6(5~^0)-0S;fDe@ja287u zY_gbON!pgd)!1xq^oK8S^=0{s-~RZ~d`o|ALXuHrL*1Z*87JO;a%!zvL3;8f+wYTu5r!>Eqq?zv2MG3U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+qXA(iBJ0RU2S BUAk14uD!S3 zd&(G2W5QqYPsGfSXv7%BC@S$qBB&^sNPLhW8nR#vD&Uity%?Vue!X*Xi~8WnIp==o zeBb@f`Tc(1`Pnmb(~0m>p$-Y|Ey+Y*Dj6tgu*AYw9>1Rq?_%bz0vne+k|&)nSOhv} z7AG3zl<+*|M5Se3F_}duF%oq zWs|kD-35ym^quxa18{wOQRy|QuI5RJTAZ0xM1HbW&9f54-kA|aQ6$espdg(j=|t~f zk|;E*Dx^j75TcaF6w*7;KQNRgL&Gpe1_#N;;Z!OK8_k^V><%@z*@09cgTq7p>EuJ{ zYCz*kZ>+1M+3j!1Dx?o`rw3BWSRe9+yFy|2s?g>w1F6K8?PODOJ88jB)VE5W*0qxR zIR0o!ALWgw>ejSF6U7FXiBaDg$umjHV`LJzhBisExVrC{l&<6ul5r;4erVF>x;-Sf z%MmcUJEGlkJP?gUqw!D|SrdYGHHTK8K~m38L}%lwQLL2omD95~F!byV>`>H^tt&=` zwhr_UCHrEvg0~|U?VPO@M4Va_ieuydYhEJ54utYa_Mz0i$&N4M=$#Nnj6|4*_c*e+O%3}yS#tOP7I3W+* z+M&}D{G}Oc27BsjKyr*Ed|(P8)IAE*j#0FMv)$bGte=4$Xy@KO+y4rldD)3-gqHST zu2`}1!8nVDqp@6&ty3(m}gY8f^#M8dgeO2I#oy}`1%XR?AJM?vMqnafrWZI60kEIWf=@+Uh!t-0j(YDSS~v~0#S433>PPS9HrYT$vp zPCa(;KINKRx?Vh{t9x6ge*9ocbc^EZ{2Ubvk=jSN0GqgMba4^>jZE}?{=aegdVF%V zID0~i5Q+Qi0S4f~E{uVDw#KUNXxIWU*7!WbhTz3^Etq-nO6{Od@;MeDYEN_Kfo5CzXRXXFy4Ui zJ-G40idd-l?R}5LH!trw5KcwETzIcrPaPX}Izo3296f&ya)>aXxnIBY;q>`c>TjF> E1mng1y#N3J literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/9guvpb6l55h1t9aqaa9b7qnp1dnnelkd b/bats/helper/testdata/20200113/.dolt/noms/9guvpb6l55h1t9aqaa9b7qnp1dnnelkd new file mode 100644 index 0000000000000000000000000000000000000000..40bcbfc33ba5f0bef4d41e26ac1e3cc958162bce GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YaQ*)lcF*uu!%*f815AUP@3EYTv-IK|Z1BF)k$$u!N3 zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+{oso|7zE-=l5a)z5D`JFU4o#84(D(V=Nvx1@0=NJkD>Ll zAn=5u22>EE25Qe;B8aBClsm}kjVKY+Z4qS5r!8d6!89PAj~ZMu<+E_V?@h)Y%$ga8 z)xn;@B8|AmLZoCf-D*ezit76a>^R$U!t*D*kQ>4aC>JCsr0y<$ytUq0A9EVn>5X&A zdvot9)suRGL^Kq<20;DF8eJ)S{RhOp1y+5NXYug(^&J&pWg2mj_%YqP0F1|(I{@Eo zp4~kSnvk?q5@2|w#sr4xGGEy4m>n@Dpw?!lxMl(qw*r`mhqnR&5K^Qd{psY)q0#r* zV9mcBI@8!x`vaoZ96RFA|jsDlJK}KWeJ<*?ZSjA@8GJNFE=TIoWX{b?y<5eN;da&+hVFf zHMvOwj_}1s03<~SbqGy_47aT=#~iNTSnA*O;NU`mgY@^=^0}F6qI5X_7Nj=Fr4+{1 zWgz|7GT7C=cxmLBCLt_Iop+5>;_|M5a6u#erS<7i$I5Ky&uzbUc8A5$wNtG_s)8DE zds#B3QAqqQ=g;f^`vn!2e!Tkp7ew*|AC~4v?tf#kETQyOnNR-bPDz^~V zwOK%PF+*w)$Y~2PB#RcNCe+S*HnWja3!-TWyU2FnP7C!r#5?WSHw!k1X-Sh*faB>R z_Nh%g7-&e=iym?@+|eq<`)a#wr`PtV%4`=?hTMFl{Bd@CJF%lcv2RrGdK6wMeV;2| zQS!*g9-~14D6jPO>G;ZU;@6?y$LhV}^|h;YokwQ`JsFjX$SL4c^MX2)oDihPHNz+F z3NgqL2@4Vk29;1^Z%)-L;xNPNF?>Q8kQwT6FqNUAN>W7ziaxnTL)6UiK!%UAid>~} z0ZGynHFQa;$+Yqh0E$VRg6mO9t!(p5VqvRA(jQ1+er=eR7V${4Iak7fQ6xfIHppa~oh0-)$X2qYT1-U|*t2T+fx zyt%l#@#Ry#vMN2`G{V{L-G#>I{!d{~I8vnrU?f`J6gV$z3f#789bCu|lPZ%#>tn@O zrf#aEsc$j+`P^1bn`bD{{N(&14a6Z;-=Ql^g)!^-_NyfSLHong%jq`a6Vg|6I)2=rh@ zG(7?U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+w)|AXVASW*|M?bkJHL)a> zz58+MttpwVjwSZT^Z%Vq%P$Sfn8?DImBM!8ghiY5`%8VD3=pu@Lp|^xW7)nNQV+AA T0fiW$;>Z7Qy>Un-`CR}2fvHko literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/c8dirve58o6npl3aufbupn3c2pt55el4 b/bats/helper/testdata/20200113/.dolt/noms/c8dirve58o6npl3aufbupn3c2pt55el4 new file mode 100644 index 0000000000000000000000000000000000000000..d2c48a305f5d308e2106d5c722a0139e759f2d0c GIT binary patch literal 1069 zcmb7@Ye*DP6vywqGqbZJyRMt|Ft8+z>|yI8)0FL95)`ymUK@lZbQ4~ZJQL;w#Kq8_j4U-_!?yOlG)rT(k%)P^$Id}fQ^PjU+ z8ZJ%?i!BUUL04lD&13-0xz}leE=uAW9j0$#Jmd*4=$dI6SkWw!0Xgr~9Pe}* zc`|c`*6`M@sDzxFZt+@7RUJ`m;E3q}z^#}(xv_X%=A#V&(hZ6xB8t?YH5`!;iZ)Od zu7dyohH5=XmhvFEaKRZ4a+adian(+UDY(_Sa$nErR*=hCN<=a(9ErMXK$xqcJI;;P zfHXQrO1gtfghaKKz1v9<03K)0R$juP%N%3juqq+i(3?!Q<846R6o}sb_#sEzW)@4S}VxH`zy9O%kw?`;1&v?OFU#Xp$+ zjv@gf!NC4vhV%a9JqekR^*1NL{=kVGF5t3dA!PF+1AaP@y5Sb}kaLN;YVl&2H+0>C zj)Yo*A0Y~d1r|8>iOhJG&Oh;$2~ zG?p8S12Wgg!Nq}=kr6l)a{vbA<@;ncX4dp}mX;L=MdC84u(Uvw z!=hNk&i5QPmKV-y@2==CyE?w3a`Dyu2WW)SN%Ku#y@W;6M~pA4ieRz6-qAzDRLZG` z(;j?v`fJBlH7pF#4D#B!?nTWJY+91R-fLaak#el0>)BqYUJN{c(sue=B~7D@tOePc z)HLyrHRglk#Icg0Vbv!X61F7v;Gp#MxUz1Qwc?IGc3;+G)%8bc_~N{AWU_&F%L~r* zlAV3S*-|84lXyka-DK@gHgB>C7JFiSE%TPw-W93&)mP%R c!$-%JjhStG$U8I%GMI|-OYxhz!iUY@0U+p8J^%m! literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/ca9rtjbjd7n5pkodo3rsl6bon0s8qe4j b/bats/helper/testdata/20200113/.dolt/noms/ca9rtjbjd7n5pkodo3rsl6bon0s8qe4j new file mode 100644 index 0000000000000000000000000000000000000000..68b8f7b692c5d475b29f3793d090dadefee95a37 GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YaQ*&^A*!qmtp*~HK!(b&M)*x1m(FeS~%GSx6CEzvxU zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+}tD007oA BU6ud< literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/csopsqdj2urggh85gbsfth4c9lf4r8vb b/bats/helper/testdata/20200113/.dolt/noms/csopsqdj2urggh85gbsfth4c9lf4r8vb new file mode 100644 index 0000000000000000000000000000000000000000..995b973c3de14c4210ad927be0677d853af208ef GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YcGG%+>RJlQxk&BQp(FwHR8JT1xGG%>}(G&MQZA}P&` zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+f-(xca1YEm!bj}nZr_HH8QLM{=LX1%HFaNjRIHZ#NE&u?` C3u1c! literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/di7sdosugcarnn353e8ldbnlts9v42s5 b/bats/helper/testdata/20200113/.dolt/noms/di7sdosugcarnn353e8ldbnlts9v42s5 new file mode 100644 index 0000000000000000000000000000000000000000..5cd10ff7dbedaca00bfd7ea640b28257b53d7d3c GIT binary patch literal 192 zcmdnYcz}(8g-N(5HLX}bBQ-IlSU)*GFD)lCxrAMR&$phB%v`fCh@JnFy?Fuymz%@-d}eX7A6r{Erq<)^5p!S(%if< zU4|){c|g^9i8=boMX8A;sqEd4Q*TYlbagDTKc4^ZY+8P4SjI#a#(8avc$?1~f3DK0 k)MS8w34umw@hasTCVg6}yBsLQ2o>M_f9s7yD#`Bx09u7eDgXcg literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/eiit9a47igil0id02vhgpq4g72ga3dha b/bats/helper/testdata/20200113/.dolt/noms/eiit9a47igil0id02vhgpq4g72ga3dha new file mode 100644 index 0000000000000000000000000000000000000000..d4c2af4cfb9069e0058c8099377b0b0add76af23 GIT binary patch literal 229 zcmX@k_@R`IfrUv!S3fPMv^YcG%sAB`%_2E9)yyc>C^^l@%+%P}$RH)n*w7TnPf29g z(#)vM@0T7p0~Z>u01UrWETZ=jWy6WG0uepKh~X#x>b= z<(&q`oK1oEu6E4(>(0W$BnVQ=t0R(|SX`1?6sN_&Ai}COB{L7m$xF=9PcBMLEJ}tD004PJQTzY^ literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/es7vlqed0665gq9es3ns2uqeh75bkerc b/bats/helper/testdata/20200113/.dolt/noms/es7vlqed0665gq9es3ns2uqeh75bkerc new file mode 100644 index 0000000000000000000000000000000000000000..0e8915b9ff59df3e22c7723cb533e88241cb5c0f GIT binary patch literal 881 zcmb7?T}TvB6vt=o&g?X@+kUu3W~s?4Y1;a^W}*^iLZqz((ZkYscRt+B*%_I+Tly9e znBi1r{AxDOg)5n6=OLz+dIkrC)3LJ?HxcGocW#fJ{}z~SEWhx^W;i|r4jVWBA_(&oX%W*(wT!6D*{`lEaTaIgQ=cV{m5uH0gKgcG61WC zOwxJ37=)ZAN(`~^(0#DRn^iQjXp!@if2G$gh1sMN>kWtTmq>0 z91p*!=hDU+wCwLcdRdyz>i9d5MBKzVFmXq-zCW*-S6UyO3I`%0ham-py2iux!th1q*y2r#d2R^xm3pFSh}>T!nB)%6*C8h zV@-AYhc8{G07%B>>n^_t1>J>Bl;i-9n3v(|zNG7=1Mkn1@}tJN>5kj0brc0`@m_PD zBM5aQYNvAv!a?WuV9!NOfwGI&M2JMD^RxJ_Cs2C`RZpmElad-b>F=heH0gPX~20D=O^4^jz1+Xa-zo#U2x4Y8r^-S`~0$->Ce(!{_lEhX6$$TUkfF}GmX z(#)vM@0T7p0~Z>u01UrWETZ=jWy6WG0uepKh~X#x>b= z<(&q`oK1oEu6E4(>(0W$BnVQ=t0R(|SX`1?6sN_&Ai}COB{L7m$xF=9PcBMLEJ=H%D{RC2-y0ip>Ff?%EU$U!w)0? Sg&3jY$Nz7=aY!ZkT>t>S@lqH7 literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/frc0ef452fhh97o534e7lol2b427lk56 b/bats/helper/testdata/20200113/.dolt/noms/frc0ef452fhh97o534e7lol2b427lk56 new file mode 100644 index 0000000000000000000000000000000000000000..2f1f2ad24e2a703dd0bdb792d43f2e43fd12574f GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YaQCE3h8(IDB}#LOZs#n8k!%`C+z#V{?=!oU>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+o?WMM{#1nX#prL7JsevSC`9rLmEjxmk)ys#&UWiiLq0 zyC(mHB0EF5>FcboS?v0s;I6l;y_1EBNw6q2tyn)JH8G`FKR2$im1Z0#=!s2UL=mn4_Oul$uzQibL^s$u9yoBFf)AeT?967KeRlu9|1*PJ zo0Jh!>PQSP!4yMLG4({uumvDU-bzC;RiajyaO5f>lkLcgY1q`lQG>D!DEUU^`Nr@l zGdC|;A=6E9g4~8lWh0^Mt~j=E%yt3bjoLDMpt7mS@p=IH`lz8Ij@94|93u$D>p6-y zLI8lkweDh5S%}@F&{!AyR@B%i)wm(%;A(gI_S1u_!4!!`W5lL77WdYIh*ZmWoE)qL zS$u+(^oD>Uh4}6@Lm`kGnyaQNmzTG&f&e^S()sBzOm;~E#Sxt#-ZC3)vEyY>TNaG> zynCBx%I?cm13kfhSGEUbW@URgl$8TB>=Yl_BAR%*qA|Jd#gS*!|FXTSc~zHxMDdHi z15Cr`5dDMS?^se$QaqeL79`(K_QSv##k@(;AgxL<`k2HIa)!a zL{pU_O)bKuC8fnBb4$hPnR~2-g%b~+nt!k4!q*MevoGw}$s;t9nQ!~+2v%)BI|P~@ zRjBCi9&CTlWgO}oefzUJux@B^eSVl1kk85W&TNWdn-WXB)w-x7V_#9{!xpHY2|l{p zcKAy*&!e0PGbS0N@%wpem<9H;?j@Fib-!W}Oo_N_fIQeAtz1kOT{DMzH8W9Dx0i>T z%c`2aC(1sriEmoTEa!&JbnI`>E$F-o&bP8P8g5j!cH%u7PgshV&G*uqH@ykgPCa^O p!?C3ow>@}0d&_a-&CT1r-WF@%9eamogN3mB>$(0bQU>bG4HQC z3k#D7tJajvJfMQS#2o$PqSVBaRQB%2skf$Nx;mEFAJ6}HHZ8w2EMp=IV^k^MdZC^g ogKsQJyBHwggU&QNapI_ql|yZ$G*>+NdqWMR^h&)ih`p@NN(iTz>UA?Gu*mX)UdHPmh4a=9%P zc~O9kiJgU+cuN@Bo6j46uF|R03^YoMS1I2x>C;l(oi4Qi|1Lc@N RihyA6|E)I;sU*J(000~VU6KF* literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/jji5lv8nq265dpk6r11ug3gb6ih81hdr b/bats/helper/testdata/20200113/.dolt/noms/jji5lv8nq265dpk6r11ug3gb6ih81hdr new file mode 100644 index 0000000000000000000000000000000000000000..47faecd50819655eb7ec298873b9937a9d2edc55 GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YcGJk260EyXO+Fx4{6+|Vq=BGtmk(%3x3%-q-{Ej1;H zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+qXA(iBJ0RY-0 BU>N`a literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/ju51cbttj99itbsbk2svu7sij2tu4rhl b/bats/helper/testdata/20200113/.dolt/noms/ju51cbttj99itbsbk2svu7sij2tu4rhl new file mode 100644 index 0000000000000000000000000000000000000000..2820e12a57cee57e3dbba2481ecc9ffb44907975 GIT binary patch literal 1554 zcmb7EZEO@p7~Yw?z2z>qUatWZgE;hxl$5*P-dDe*($b@;wmmFIrAf){-0o~|b9cMv z?p{Bz{wN6`AO?&`A~Bj6h%}0c35hAyC=wtsB*YL>kzgW;{@^1-{ecmSb9<1$4}SP& zKHiyqXWn_9=gl5`>aS_wVn8jdVW4|3+1cHn3>9U%1n@2&2%yv$F~(Ff&U<)II;Wb5 zHj9`RlCg!6mBSX2aLFng#6%bwq@x zNn~W{h$c{#$?8>Dn?xpEgy$l5$uZt>iKYlJsJUMr8{GjjL7;m55#{ zkkuwC86-$1RMS$mQTw5x%JT!L%fOnHLq%*_#IUylXtR_fMO;~kqR4wTP!7^blBj>St+59oSrK*9Ea~3gM~;ViwN9j94T=cSC>Up^re~C4xM!GY**5G&f)Jga0B!6v%km)PWjX+}Z25A^ zmQCT+_ve&fz?~U4YhhYO&}r!7CfBpI`^D+$6@l2IuTPDM*Y@StYoe>x3t^2t0FP~XW~PJP7`QjjJa@)%(e0J>f|Zf88AI1C;IeU=E*j{d#m!wxUAukrw-R65_humm zzk2QIa_nO2wl{D-8H30}fcTn5#ep&yG9^A?yG4f8+D7^9xSsTefcGNyq>P z09C;)vo}X{$>fghx^ZainUT8VudbW8p!|MkZpWvM#!n1-pcCg_m}h9)IM4Xju0MAK z-1)%8IABAtNhy@gTvIEKOL8_Vla{Q~8fi{oArVm$ay%hKF`Z)E8s7nugzY^|y|BWvjuj~!}-Eglttc{7+x7BTNI^beEl8Q?V z4HudugJ6qr`>vBK@2Sa7>!ox0!UaVy59JOz!5_-=zK4ZZ5pZ(P7cZQ@ab+cS9s6U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+o>rs*#1EnW1Ttr4bOCC#R*D8JQ&+7@MY=rI;m}o20R8 z@=qwTGnAXY&ib0guKx+{db`>?S(umvi&E2y^)pfvQ;PL-6N^hyi`cs#r{0>9>FQWw ze?0%+*|hx9u#AZ;j7%b6m6>@!C3%TC`pHG9i6yBx6wgtg?9R7oWB%fe9GMIdu$cMx d)CYz3)e#r|@9_r;F+#;>|KED!kV^8q000nROilm* literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/m297l94np7ub1bp8irhpf3eta6bpegr8 b/bats/helper/testdata/20200113/.dolt/noms/m297l94np7ub1bp8irhpf3eta6bpegr8 new file mode 100644 index 0000000000000000000000000000000000000000..058cb989a5da19b46f77435e50c5403f0ec25764 GIT binary patch literal 923 zcmb7CT}Tu`9N(SWy=||v+q+D(&?F2qwM$bw3pFzn5mdpW zwd}#tD2O7WL|-iXFc2S7qSCOAK+!NU6naq9^76&s8WCYn$<&{*L z4a=7VSwv#q+68UG54<2ts-{4Spjq?3;f(=c zipr|xwK^Zt<1y$}f!;_Mu?z$NAvN$Km5yUWZ*+dvD9Rp<7ahDJ%NnU)W2<5*fetzZ zrbY$Tb&Zp+d~; zTQMUUk~9Lqiu9aa7F4FaVfI#aqu8t9SpB^L5 zF=bH!agU&QNapI_ql|yZ$G*>+NdqWMN_wE=o-+*3U>yOexk+&d*EB$xJR`*WdH4=OZ)M z>r)1^< z&B#m4(N8W)O)N=e?|z(mYf7f8V~PFo{C{WD@=L=qCbBTvd@1Be`QXXM$iyxxr77ki z)S7?TbeN5a(SSjO z)xZYLcIN(KQx2F01_lO3m}NjV!^|&Ci_h*mmo?WfnidTL9&IRrDc+(VUj_rfr+t&MQTz?qH(HuYLclj zyC(mHB0EF5>FcboS?v0s;I6l;y_1EBNw6q2tyn)JH8G`FKR2U>bG4HQC z3k#EotX554YI$;gPHAo)yPSQH<=l@q|Fir#ytvrEU>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+xhSABu*_K}Q)N;9A%H^L0nf8aLl`Klu_U#0VAt@_*}%Ln_Jd0s!lW BVMzc0 literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/oarahke38ufh3tmnfpafuvb51dfbhgmh b/bats/helper/testdata/20200113/.dolt/noms/oarahke38ufh3tmnfpafuvb51dfbhgmh new file mode 100644 index 0000000000000000000000000000000000000000..0717c58dbe06db84e9462ee8471497db6319539c GIT binary patch literal 783 zcmZvaPe@cj9LHy7=e@UYUEN*X!YFHrJe2Nk79EOAMXghm6-B7M#`k93hwsn!X4Voq zL_tJK6ln*eA_6P$5dFJUAa$?^EfPbsqUg{e3cYNHYPYc{I`ri?%rL+2{Fu*gW=7el z%8jmVo7{(O%8BZS^6XuMa3W)aG9ASl41*dm=8A0EbUI_6doV^EBc{7n)^=jLL~UYP zsLUWemh048=7Fp^e?FnRMe`NAsmDy$LB5*AYU~i3qLQXx*4Q4?>M|Xsa?_@a6FU>W z+WYQeAzqSY)YJa%hKA3LJjk~y8RAigGe3aJ)8lnRfwSwbzdi!3n=NlAPh9-5MQ~I+ z#!5y_M5S(GW$C7u07%m9#3cYQ90clulN*kKawHTE0SWs3N+7-_tp*L(;+oN+d9KT$ z%t?nunT!-wl8W{tEO1$X>1jc!c{HWSr9mGGg`pe`M-?@&Q(9c!Bxs?cS8lInl3LvC z=&tBkqZBzUg+!Ay-E|oEh$-$~Y%)z?aLr9=nJz5o4GbTY`#9;8)X0L`NDW4zMYZ)B z@5xYEIEl@W90Wo5!jBMyN(2HNU%UGaumD0n(xEH4%X?S%kBlZZft5q8*Gle<&%iO~ zE6C^O!^wdlLaI^uq|MctGIadYKzDiD^6M?NhsIJLXYU`qR^?5DB`91fY+)ro4n=Gp zhXCEkP0(9#Lw zaH{lvps)JP<_2Cj>gLB%ZgzM242Dbh?SOwu0HMK1eV!F2cZnqg09A;2=-<)<6Zx%u Z>1AxnXc`tdB!&<^Rk$w)|AXVASW*|M?bkJHL)a> zz58+MttpwVjwSZT^Z%Vq%P$Sfn8?ET)>i3Z7Qy>Un-`CR}25LHt~ literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/ojdo9hafo3mvlko0cefqcom7os26utln b/bats/helper/testdata/20200113/.dolt/noms/ojdo9hafo3mvlko0cefqcom7os26utln new file mode 100644 index 0000000000000000000000000000000000000000..f52f1557b31e1cbd9010d8bdff155790d6a06548 GIT binary patch literal 211 zcmbQu_+b_s12dC`u6|lhX>o?Wd6KzNnsJi3d77D}fu(_wxw*MviiLTaiHVV=si}b> zyC(mHB0EF5>FcboS?v0s;I6l;y_1EBNw6q2tyn)JH8G`FKR2$im1Z0#=!s2UL=mn4_Oul$uzQibJv9#ZF;Ci74hTM-CljfPlrX f&i<19xbzc4^D6cWKp{q``0W2%ZyZudeir}$un9~) literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/os1po1dclurjkflegl02usl2r8rkg2cq b/bats/helper/testdata/20200113/.dolt/noms/os1po1dclurjkflegl02usl2r8rkg2cq new file mode 100644 index 0000000000000000000000000000000000000000..d6e77f36f33f002063d0a6594311d814a496986e GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YcG+#)eC+0Z=2D9OMe#l$GZ!ZO9u*fh<;)HKy3#nRH4 zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+ literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/q5eq2e7gn1osgqg6bdqctgi7o7lapsik b/bats/helper/testdata/20200113/.dolt/noms/q5eq2e7gn1osgqg6bdqctgi7o7lapsik new file mode 100644 index 0000000000000000000000000000000000000000..1ab53ad2dc16a210b89edcca6a9872e44ec57472 GIT binary patch literal 229 zcmX@k_@R`IfrUv!S3fPMv^YaQ(LBjGInB~6EjiV~#L(E>#N5QvJki+DDACM3*~r+C zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!hX8Vei_$f z)0KA`7;`oS-n-f{@2@)x3zHy7Ew7G9ZenpsYEhgP1A_>w)|AXVASW*|M?bkJHL)a> zz58+MttpwVjwSZT^Z%Vq%P$Sfn8?Dot1ZccsY){Sv~1p51_;=?E`(*)lbGF|$4%0E TfkKQ>@#Fuu-Z-R^{4M|h&hb!T literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/qqc5268agbqc0nqdud6gn7m202teffnm b/bats/helper/testdata/20200113/.dolt/noms/qqc5268agbqc0nqdud6gn7m202teffnm new file mode 100644 index 0000000000000000000000000000000000000000..ae28d8ca6d1768bbdc1270ef23f534fac81f31d8 GIT binary patch literal 1069 zcmb7@TWHfz9LCQ%Nt&j%uHC%DRGf-BwNBmEPU|MSi6B^}vWH4MO;TH$CM7wYQ&2>3 z&dY;Wd{Fl=W!^;wipU;R6mN+7;Ou00!5gB?DKa0#&6Dc1qCR-Y$@zzz{FCqZeL2iD z3ywM|sw8j~CK&RPuBH;2$pKbyRcn$iD{`d{^OkWr^o}U$nn?^C(+J%G1<&vT&qx;K zj4tS{6v^78g6x`3L@lMNwj?%i!n6V4ikTw4Afg@-lW_pqcubQKLwm3qPACW^;|#&8 zApn45nzqxWtd5?9x=}Xzu9&u3SYd~lfy?a`o6q(w2NMMnODHD6iKMF@goS#x?Nnbq zaI-1e(p5KC%5m%z*uY6WN@=X~{y!;zb91vh#ZMDsxY8%DPHKIV>8wPM|HL zmf}ZEuC;o==W^=lF4~4 z{kKR@z*A&pCJ_3UGRQ;dL`aaicOhM(ZZ*B#*DxwH;dn66cqj6@w`0?>LZb_eN7OBZ z+`Q1A2K1;&1H1XS>=W!w*#L*8%3B)!Gg`Xn+L;~R>=0Cx%VjMMWFepqp$ fb;G;+llR0AmK@Ec&#-jT!Oa^um%cJl>RI{?j7VNx literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/rcksm0pvt2fop4deb2tf881mo0vj4ih8 b/bats/helper/testdata/20200113/.dolt/noms/rcksm0pvt2fop4deb2tf881mo0vj4ih8 new file mode 100644 index 0000000000000000000000000000000000000000..3bc9ec8ae22c3271c2ac4146a9f0cf7021ad0834 GIT binary patch literal 229 zcmX@k_@R`IfrUv!S3fPMv^YaQ$<#PG$t2Cxz|zPhCB?$n(8wYs$vDwCB{eBI%_zy7 zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!hX8Vei_$f z)0KA`7;`oS-n-f{@2@)x3zHy7Ew7G9ZenpsYEhgP1A_>w)|AXVASW*|M?bkJHL)a> zz58+MttpwVjwSZT^Z%Vq%P$Sfn8?CtxqH&W#)Q?A_QX7nVSs?G*IgUfHg8k4H@>p} U7Ep*0Dt`R`)*FXZlHUaY0Jxh{@&Et; literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/rrbqpqt3l59s17rbva7pjrqhitbe4cc2 b/bats/helper/testdata/20200113/.dolt/noms/rrbqpqt3l59s17rbva7pjrqhitbe4cc2 new file mode 100644 index 0000000000000000000000000000000000000000..71ffb97f2a2dbd98345c312f2aee5e59103085ac GIT binary patch literal 262 zcmeyu_@R`Ift5)^S3fPMv^YcGJT=KM&Dg>sH8C~C+|bO>*wn-{In~@SF~!o*#4ydA zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#Eotd>GvYI$;gPHAplnJ&YW%sim#yu=*+?%jcq9-g#0VAt@_*}%Ln_Jd0sxNG BV1WPt literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/s69lvejsvg9so3l2nsquavmbai4dmu03 b/bats/helper/testdata/20200113/.dolt/noms/s69lvejsvg9so3l2nsquavmbai4dmu03 new file mode 100644 index 0000000000000000000000000000000000000000..cf28c6f19d27c86cc8f6c3c0f84dec04693c7c37 GIT binary patch literal 934 zcmb7?T}TvB6oBX6`Ez7t88)+CicldRYTeu|f6G{PUwnv6ix9>;Gk4v^`PpXfBKDep zAw-4{7}!G;iV-SQWG@v#4-r^_lmtZMSrH%rCSkPY3I54x;&Xh?cZDN-oGgEXbs`|B!H*V4rhN<7K z-FppkGZIgbYGBAYcCRb0Bo^nELW%M2sgo-$K@?q89NQ*9@G+@n09mAJ;+-=?EnROT=CUziY3C}&-p!2h z63>^XewxU~^#zC&kPmfkZT)XNUViZ3aB_nj@kXMdatjbYP)#v5dFU~gEH1eMa^nKS z!oB;#Nh9l~!d0;(uBnRXQBAK@qcMzQ)hMDLs;SY`h^As)tO#Co4o7xfzE!taJ-^GWa8LPl6~ zFe3OL$;Y4G-Lo+kUKb{&m-|aV*R)46`{jM^Vaw??dS*AY)3evFmo%1Wyr6L{f1L8$ rG8zgtKA&uQ^O&EkYZz|ryV^fzd=u4PTEo$xi=A4({pwMf_W9Tk_ZTf% literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/srlc19tj78ldn4hbb8duso90i1vugc59 b/bats/helper/testdata/20200113/.dolt/noms/srlc19tj78ldn4hbb8duso90i1vugc59 new file mode 100644 index 0000000000000000000000000000000000000000..e094d57e4c6139808844968770ae1b9ec5f90e60 GIT binary patch literal 249 zcmX@k_@R`IfrUv!S3fPMv^YcG%se&8D9Omg#Mn5++}tqP#3IEa%^)$&+{8T9*vQh5 zU6X%8k)5I3^mW$PEOz}*aM#<_-pRtmBwUo5R;-_qnwV0opPZkUmXn!W!mhvPThB*k zuGtsF&j04Hjs54CtsTR{$|ML<%d1n7n^;_uTEu?3&3+lzWYd**8W?jn1>U>bG4HQC z3k#D7tJajvJfMQS#2o$PqSVBaRQB%2skf$Nx;mEFAJ6}HHZ8w2EMp=I}tD005-sT&w^9 literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/tmie2h7f80pblg0ojfk0v50qu8s97mpa b/bats/helper/testdata/20200113/.dolt/noms/tmie2h7f80pblg0ojfk0v50qu8s97mpa new file mode 100644 index 0000000000000000000000000000000000000000..ede082b09c7ee8ddfec490b61f2e30a2f144ff62 GIT binary patch literal 309 zcmZQ#VPKrS)j!_y0VkVter|4N2{TJ>YDpp|0|R?OVo_>dNihcl18Z4gPH8H8LvT)F z!QD2sI~-CUJuc5X^f#81hk;S={;j(%ADr137@0J5_0w`ni!=01j13G8j4h3mOcTwL zl2VLJ%uS3;4U!B^O^i}f4NTM6HTfqL*%``BUuS*IV%Pr!cfDQhoh(fI9!IN6CUEkk z!|$vXvwz<)jv~F)$qa7$^1nOY{ QVi1_|f9s7yD#`Bx01H-UlK=n! literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/u62g6ma6evirqjb11i0up0p1hppb50ou b/bats/helper/testdata/20200113/.dolt/noms/u62g6ma6evirqjb11i0up0p1hppb50ou new file mode 100644 index 0000000000000000000000000000000000000000..ca0a5d5761261a4f1209f18936be5c3b703295d0 GIT binary patch literal 284 zcmeyu_@R`Ift5)^S3fPMv^YaQ$-*cx$-=_i%)%ti*xV?^+|U>bG4HQC z3k#EotX554YI$;gPHAo)yPSQH<=l@q|Fir#ytvrEUoovzaT@~!ys^HYqTnJb YtyR)6zZ59M2o?YGf9s7yD#`Bx0EMe*g8%>k literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/noms/ug6l7o53ntp50f252u65cj96om411v14 b/bats/helper/testdata/20200113/.dolt/noms/ug6l7o53ntp50f252u65cj96om411v14 new file mode 100644 index 0000000000000000000000000000000000000000..50fc9117c9874d15a578b21b5457111e0b7f199d GIT binary patch literal 926 zcma#uz{bEN#3aDL&m_bqu#J_8B_**WQQ(@G2qOan1K-tkXYa|s@lE*uUtpt(z*PZO zEd~}&Efvn<{M^)%jLf`rS$&IhOW99+4uGim((T&Quf5;_=-ncMX%u7eeO2nSx#0~)ecC2AbS@%9N0nrWR!}* z10;J=&{oip1?00BTs~uDXJq7IV&Y6;eG`+PT+F_#?e)|$i5R7ofwmQA)1H6W)3idn z=q7^#6EL=zm;~54|J`5!BDWh1PCW7sUl>1>vN5nSY3S;w<&+j@=o=cD8z)($Sr{al znHeM-Ct9YNrCKH%nV1_}CR-$%Td-^LPbji8l$*ZJ`kKYA{|WATyV^Thn3#ltkzcHz zk(!uNtPhODw4BW35_bJP-+DeWbIraWcK$bqZR|hCZ0#5pRwhA^T3(%s+{EIN)FSrN zZT8E!CY!Fj)4-UsDe&Iaj(LCGSy-4vWVICXQp+L9rA(J$3NTTm7Ud=8=qDGYCYGeK zcRx8YTN=HrvVR_HKZ`$K7mDOY&ohmXXTz*=S+s&mWbwE8V SKnw)TU;l5taY!ZkT>t>DRW^M9 literal 0 HcmV?d00001 diff --git a/bats/helper/testdata/20200113/.dolt/repo_state.json b/bats/helper/testdata/20200113/.dolt/repo_state.json new file mode 100644 index 0000000000..793216b5e2 --- /dev/null +++ b/bats/helper/testdata/20200113/.dolt/repo_state.json @@ -0,0 +1,8 @@ +{ + "head": "refs/heads/master", + "staged": "hlgmnafjvlg8curcjc14dok7k1h3mqci", + "working": "hlgmnafjvlg8curcjc14dok7k1h3mqci", + "merge": null, + "remotes": null, + "branches": null +} \ No newline at end of file diff --git a/bats/helper/testdata/20200113/README.md b/bats/helper/testdata/20200113/README.md new file mode 100644 index 0000000000..113afd10d3 --- /dev/null +++ b/bats/helper/testdata/20200113/README.md @@ -0,0 +1,75 @@ +## Overview + +This is test data that captures a repository on January 13, 2020. This may be used to verify that any serialization/deserialization changes are compatible with people's pre-existing data. + +# Branch master + +## Schema + +``` +CREATE TABLE `abc` ( + `pk` BIGINT NOT NULL COMMENT 'tag:0', + `a` LONGTEXT COMMENT 'tag:694', + `b` DATETIME COMMENT 'tag:2902', + PRIMARY KEY (`pk`) +); +``` + +## Data + +``` ++----+------+---------------------------+ +| pk | a | b | ++----+------+---------------------------+ +| 1 | data | 2020-01-13 20:45:18.53558 | ++----+------+---------------------------+ +``` + +# Branch conflict + +## Schema + +``` +CREATE TABLE `abc` ( + `pk` BIGINT NOT NULL COMMENT 'tag:0', + `a` LONGTEXT COMMENT 'tag:694', + `b` DATETIME COMMENT 'tag:2902', + PRIMARY KEY (`pk`) +); +``` + +## Data + +``` ++----+-----------+---------------------------+ +| pk | a | b | ++----+-----------+---------------------------+ +| 1 | data | 2020-01-13 20:45:18.53558 | +| 2 | something | 2020-01-14 20:48:37.13061 | ++----+-----------+---------------------------+ +``` + +# Branch newcolumn + +## Schema + +``` +CREATE TABLE `abc` ( + `pk` BIGINT NOT NULL COMMENT 'tag:0', + `a` LONGTEXT COMMENT 'tag:694', + `b` DATETIME COMMENT 'tag:2902', + `c` BIGINT UNSIGNED COMMENT 'tag:4657', + PRIMARY KEY (`pk`) +); +``` + +## Data + +``` ++----+-----------+---------------------------+---------+ +| pk | a | b | c | ++----+-----------+---------------------------+---------+ +| 1 | data | 2020-01-13 20:45:18.53558 | 2133 | +| 2 | something | 2020-01-13 20:48:37.13061 | 1132020 | ++----+-----------+---------------------------+---------+ +``` diff --git a/bats/helper/testdata/README.md b/bats/helper/testdata/README.md new file mode 100644 index 0000000000..5a4e057850 --- /dev/null +++ b/bats/helper/testdata/README.md @@ -0,0 +1,34 @@ +## Overview + +This is a collection of repositories that are to be created whenever the on-disk format is changed in any way. This way, we can catch some errors that may arise from the new changes not properly reading the older formats. The test file is `back-compat.bats`, which loops over each directory and runs a set of basic tests to ensure that the latest code can both read and modify pre-existing data. Each repository will have the same branch names and same general schema. + +## Steps + +Whenever the format is updated, a new repository should be created from scratch with the new format. The following steps may be used to create a compatible repository: + +```bash +dolt init +"UPDATE README.md" +dolt add . +dolt commit -m "Initialize data repository" +dolt sql -q "CREATE TABLE abc(pk BIGINT PRIMARY KEY, a LONGTEXT COMMENT 'tag:694', b DATETIME COMMENT 'tag:2902')" +dolt add . +dolt commit -m "Created table abc" +dolt sql -q "INSERT INTO abc VALUES (1, 'data', '2020-01-13 20:45:18.53558')" +dolt add . +dolt commit -m "Initial data" +dolt checkout -b conflict +dolt sql -q "INSERT INTO abc VALUES (2, 'something', '2020-01-14 20:48:37.13061')" +dolt add . +dolt commit -m "Added something row" +dolt checkout master +dolt checkout -b newcolumn +dolt sql -q "ALTER TABLE abc ADD COLUMN c BIGINT UNSIGNED COMMENT 'tag:4657'" +dolt sql -q "UPDATE abc SET c = 2133 WHERE c IS NULL" +dolt sql -q "INSERT INTO abc VALUES (2, 'something', '2020-01-13 20:48:37.13061', 1132020)" +dolt add . +dolt commit -m "Added something row and column c" +dolt checkout master +``` + +The generated `LICENSE.md` may be removed, and the `README.md` should be updated to reflect the information contained in the repository (this is assumed to be done immediately after `dolt init`). It is required for the repository to be on the `master` branch, as the tests assume this starting point. \ No newline at end of file diff --git a/bats/types.bats b/bats/types.bats new file mode 100644 index 0000000000..e4bc63b4f6 --- /dev/null +++ b/bats/types.bats @@ -0,0 +1,995 @@ +#!/usr/bin/env bats +load $BATS_TEST_DIRNAME/helper/common.bash + +setup() { + setup_common +} + +teardown() { + teardown_common +} + +@test "types: BIGINT" { + dolt sql < start) + maxNumOfSteps := endInclusive - start + 1 + trueNumOfSteps := mathutil.MinInt64(int64(numOfSteps), maxNumOfSteps) - 1 + inc := float64(maxNumOfSteps) / float64(trueNumOfSteps) + fCurrentVal := float64(start) + currentVal := int64(math.Round(fCurrentVal)) + fCurrentVal -= 1 + for currentVal <= endInclusive { + loopedFunc(currentVal) + fCurrentVal += inc + currentVal = int64(math.Round(fCurrentVal)) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/datetime_test.go b/go/libraries/doltcore/schema/typeinfo/datetime_test.go new file mode 100644 index 0000000000..e739092278 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/datetime_test.go @@ -0,0 +1,264 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestDatetimeConvertNomsValueToValue(t *testing.T) { + tests := []struct { + typ *datetimeType + input types.Timestamp + output time.Time + expectedErr bool + }{ + { + DateType, + types.Timestamp(time.Date(1880, 1, 2, 4, 6, 3, 472382485, time.UTC)), + time.Date(1880, 1, 2, 0, 0, 0, 0, time.UTC), + false, + }, + { + TimestampType, + types.Timestamp(time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC)), + time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC), + false, + }, + { + DatetimeType, + types.Timestamp(time.Date(5800, 1, 2, 4, 6, 3, 472382485, time.UTC)), + time.Date(5800, 1, 2, 4, 6, 3, 472382485, time.UTC), + false, + }, + { + DatetimeType, + types.Timestamp(time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC)), + time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC), + false, + }, + { + TimestampType, + types.Timestamp(time.Date(2039, 1, 2, 4, 6, 3, 472382485, time.UTC)), + time.Time{}, + true, + }, + { + DatetimeType, + types.Timestamp(time.Date(5, 1, 2, 4, 6, 3, 472382485, time.UTC)), + time.Time{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestDatetimeConvertValueToNomsValue(t *testing.T) { + tests := []struct { + typ *datetimeType + input interface{} + output types.Timestamp + expectedErr bool + }{ + { + DateType, + time.Date(1880, 1, 2, 4, 6, 3, 472382485, time.UTC), + types.Timestamp(time.Date(1880, 1, 2, 0, 0, 0, 0, time.UTC)), + false, + }, + { + TimestampType, + time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC), + types.Timestamp(time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC)), + false, + }, + { + DatetimeType, + time.Date(5800, 1, 2, 4, 6, 3, 472382485, time.UTC), + types.Timestamp(time.Date(5800, 1, 2, 4, 6, 3, 472382485, time.UTC)), + false, + }, + { + DatetimeType, + time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC), + types.Timestamp(time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC)), + false, + }, + { + TimestampType, + time.Date(2039, 1, 2, 4, 6, 3, 472382485, time.UTC), + types.Timestamp{}, + true, + }, + { + DatetimeType, + time.Date(5, 1, 2, 4, 6, 3, 472382485, time.UTC), + types.Timestamp{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestDatetimeFormatValue(t *testing.T) { + tests := []struct { + typ *datetimeType + input types.Timestamp + output string + expectedErr bool + }{ + { + DateType, + types.Timestamp(time.Date(1880, 1, 2, 4, 6, 3, 472382485, time.UTC)), + "1880-01-02", + false, + }, + { + TimestampType, + types.Timestamp(time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC)), + "2030-01-02 04:06:03.472382", + false, + }, + { + DatetimeType, + types.Timestamp(time.Date(5800, 1, 2, 4, 6, 3, 472382485, time.UTC)), + "5800-01-02 04:06:03.472382", + false, + }, + { + DatetimeType, + types.Timestamp(time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC)), + "9999-12-31 23:59:59.999999", + false, + }, + { + TimestampType, + types.Timestamp(time.Date(2039, 1, 2, 4, 6, 3, 472382485, time.UTC)), + "", + true, + }, + { + DatetimeType, + types.Timestamp(time.Date(5, 1, 2, 4, 6, 3, 472382485, time.UTC)), + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestDatetimeParseValue(t *testing.T) { + tests := []struct { + typ *datetimeType + input string + output types.Timestamp + expectedErr bool + }{ + { + DateType, + "1880-01-02 04:06:03.472382", + types.Timestamp(time.Date(1880, 1, 2, 0, 0, 0, 0, time.UTC)), + false, + }, + { + DateType, + "1880-01-02", + types.Timestamp(time.Date(1880, 1, 2, 0, 0, 0, 0, time.UTC)), + false, + }, + { + TimestampType, + "2030-01-02 04:06:03.472382", + types.Timestamp(time.Date(2030, 1, 2, 4, 6, 3, 472382000, time.UTC)), + false, + }, + { + DatetimeType, + "5800-01-02 04:06:03.472382", + types.Timestamp(time.Date(5800, 1, 2, 4, 6, 3, 472382000, time.UTC)), + false, + }, + { + DatetimeType, + "9999-12-31 23:59:59.999999", + types.Timestamp(time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC)), + false, + }, + { + TimestampType, + "2039-01-02 04:06:03.472382", + types.Timestamp{}, + true, + }, + { + DatetimeType, + "0005-01-02 04:06:03.472382", + types.Timestamp{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/decimal_test.go b/go/libraries/doltcore/schema/typeinfo/decimal_test.go new file mode 100644 index 0000000000..f1bc4f7673 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/decimal_test.go @@ -0,0 +1,50 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "strconv" + "testing" + + "github.com/src-d/go-mysql-server/sql" + + "github.com/stretchr/testify/require" +) + +//TODO: add some basic tests once the storage format has been decided + +func generateDecimalTypes(t *testing.T, numOfTypes uint16) []TypeInfo { + var res []TypeInfo + scaleMult := float64(sql.DecimalTypeMaxScale) / sql.DecimalTypeMaxPrecision + loop(t, 1, sql.DecimalTypeMaxPrecision, numOfTypes, func(i int64) { + if i%9 <= 5 { + res = append(res, generateDecimalType(t, i, int64(float64(i)*scaleMult))) + } else { + res = append(res, generateDecimalType(t, i, 0)) + } + }) + return res +} + +func generateDecimalType(t *testing.T, precision int64, scale int64) *decimalType { + typ, err := CreateDecimalTypeFromParams(map[string]string{ + decimalTypeParam_Precision: strconv.FormatInt(precision, 10), + decimalTypeParam_Scale: strconv.FormatInt(scale, 10), + }) + require.NoError(t, err) + realType, ok := typ.(*decimalType) + require.True(t, ok) + return realType +} diff --git a/go/libraries/doltcore/schema/typeinfo/enum_test.go b/go/libraries/doltcore/schema/typeinfo/enum_test.go new file mode 100644 index 0000000000..4cea89ca85 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/enum_test.go @@ -0,0 +1,49 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "testing" + + "github.com/src-d/go-mysql-server/sql" + "github.com/stretchr/testify/require" +) + +//TODO: add some basic tests once the storage format has been decided + +func generateEnumTypes(t *testing.T, numOfTypes int64) []TypeInfo { + res := make([]TypeInfo, numOfTypes) + for i := int64(1); i <= numOfTypes; i++ { + res[i-1] = generateEnumType(t, int(i)) + } + return res +} + +func generateEnumType(t *testing.T, numOfElements int) *enumType { + require.True(t, numOfElements >= 1 && numOfElements <= sql.EnumTypeMaxElements) + vals := make([]string, numOfElements) + str := make([]byte, 4) + alphabet := "abcdefghijklmnopqrstuvwxyz" + for i := 0; i < numOfElements; i++ { + x := i + for j := 2; j >= 0; j-- { + x /= len(alphabet) + str[j] = alphabet[x%len(alphabet)] + } + str[3] = alphabet[i%len(alphabet)] + vals[i] = string(str) + } + return &enumType{sql.MustCreateEnumType(vals, sql.Collation_Default)} +} diff --git a/go/libraries/doltcore/schema/typeinfo/float_test.go b/go/libraries/doltcore/schema/typeinfo/float_test.go new file mode 100644 index 0000000000..b2bb0f3264 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/float_test.go @@ -0,0 +1,230 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "math" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestFloatConvertNomsValueToValue(t *testing.T) { + tests := []struct { + typ *floatType + input types.Float + output interface{} + expectedErr bool + }{ + { + Float32Type, + 0, + float32(0), + false, + }, + { + Float64Type, + 1, + float64(1), + false, + }, + { + Float32Type, + 250, + float32(250), + false, + }, + { + Float64Type, + math.MaxFloat64, + float64(math.MaxFloat64), + false, + }, + { + Float32Type, + math.MaxFloat64, + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestFloatConvertValueToNomsValue(t *testing.T) { + tests := []struct { + typ *floatType + input interface{} + output types.Float + expectedErr bool + }{ + { + Float32Type, + true, + 1, + false, + }, + { + Float64Type, + "25", + 25, + false, + }, + { + Float64Type, + uint64(287946293486), + 287946293486, + false, + }, + { + Float32Type, + time.Unix(137849, 0), + 137849, + false, + }, + { + Float64Type, + complex128(14i), + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestFloatFormatValue(t *testing.T) { + tests := []struct { + typ *floatType + input types.Float + output string + expectedErr bool + }{ + { + Float32Type, + 0, + "0", + false, + }, + { + Float64Type, + 1, + "1", + false, + }, + { + Float32Type, + 250, + "250", + false, + }, + { + Float64Type, + math.MaxFloat64, + strconv.FormatFloat(math.MaxFloat64, 'f', -1, 64), + false, + }, + { + Float32Type, + math.MaxFloat64, + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestFloatParseValue(t *testing.T) { + tests := []struct { + typ *floatType + input string + output types.Float + expectedErr bool + }{ + { + Float32Type, + "423.5", + 423.5, + false, + }, + { + Float64Type, + "81277392850347", + 81277392850347, + false, + }, + { + Float64Type, + "12345.03125", + 12345.03125, + false, + }, + { + Float64Type, + "something", + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/inlineblob_test.go b/go/libraries/doltcore/schema/typeinfo/inlineblob_test.go new file mode 100644 index 0000000000..de60c770a4 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/inlineblob_test.go @@ -0,0 +1,161 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestInlineBlobConvertNomsValueToValue(t *testing.T) { + tests := []struct { + input types.InlineBlob + output string + }{ + { + []byte("hi"), + "hi", + }, + { + []byte("hello there"), + "hello there", + }, + { + []byte("هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر"), + "هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر", + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, InlineBlobType.String(), test.input), func(t *testing.T) { + output, err := InlineBlobType.ConvertNomsValueToValue(test.input) + require.NoError(t, err) + require.Equal(t, test.output, output) + }) + } +} + +func TestInlineBlobConvertValueToNomsValue(t *testing.T) { + tests := []struct { + input interface{} + output types.InlineBlob + expectedErr bool + }{ + { + int16(25), + []byte("25"), + false, + }, + { + uint64(287946293486), + []byte("287946293486"), + false, + }, + { + float32(78.25), + []byte("78.25"), + false, + }, + { + "something", + []byte("something"), + false, + }, + { + time.Date(1880, 1, 2, 3, 4, 5, 0, time.UTC), + []byte("1880-01-02 03:04:05"), + false, + }, + { + complex128(32), + []byte{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, InlineBlobType.String(), test.input), func(t *testing.T) { + output, err := InlineBlobType.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestInlineBlobFormatValue(t *testing.T) { + tests := []struct { + input types.InlineBlob + output string + }{ + { + []byte("hi"), + "hi", + }, + { + []byte("hello there"), + "hello there", + }, + { + []byte("هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر"), + "هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر", + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, InlineBlobType.String(), test.input), func(t *testing.T) { + output, err := InlineBlobType.FormatValue(test.input) + require.NoError(t, err) + require.Equal(t, test.output, *output) + }) + } +} + +func TestInlineBlobParseValue(t *testing.T) { + tests := []struct { + input string + output types.InlineBlob + }{ + { + "hi", + []byte("hi"), + }, + { + "hello there", + []byte("hello there"), + }, + { + "هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر", + []byte("هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر"), + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, InlineBlobType.String(), test.input), func(t *testing.T) { + output, err := InlineBlobType.ParseValue(&test.input) + require.NoError(t, err) + assert.Equal(t, test.output, output) + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/int_test.go b/go/libraries/doltcore/schema/typeinfo/int_test.go new file mode 100644 index 0000000000..5b8125bb86 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/int_test.go @@ -0,0 +1,277 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "math" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestIntConvertNomsValueToValue(t *testing.T) { + tests := []struct { + typ *intType + input types.Int + output interface{} + expectedErr bool + }{ + { + Int8Type, + 120, + int8(120), + false, + }, + { + Int16Type, + 30000, + int16(30000), + false, + }, + { + Int24Type, + 7000000, + int32(7000000), + false, + }, + { + Int32Type, + 2000000000, + int32(2000000000), + false, + }, + { + Int64Type, + math.MaxInt64, + int64(math.MaxInt64), + false, + }, + { + Int8Type, + -200, + 0, + true, + }, + { + Int32Type, + math.MaxInt64, + 0, + true, + }, + { + Int24Type, + 1 << 25, + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestIntConvertValueToNomsValue(t *testing.T) { + tests := []struct { + typ *intType + input interface{} + output types.Int + expectedErr bool + }{ + { + Int8Type, + true, + 1, + false, + }, + { + Int16Type, + int16(25), + 25, + false, + }, + { + Int24Type, + uint64(184035), + 184035, + false, + }, + { + Int32Type, + float32(312.1235), + 312, + false, + }, + { + Int64Type, + "184035", + 184035, + false, + }, + { + Int24Type, + int32(math.MaxInt32), + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestIntFormatValue(t *testing.T) { + tests := []struct { + typ *intType + input types.Int + output string + expectedErr bool + }{ + { + Int8Type, + 120, + "120", + false, + }, + { + Int16Type, + 30000, + "30000", + false, + }, + { + Int24Type, + 7000000, + "7000000", + false, + }, + { + Int32Type, + 2000000000, + "2000000000", + false, + }, + { + Int64Type, + math.MaxInt64, + strconv.FormatInt(math.MaxInt64, 10), + false, + }, + { + Int32Type, + math.MaxInt64, + "", + true, + }, + { + Int24Type, + 1 << 25, + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestIntParseValue(t *testing.T) { + tests := []struct { + typ *intType + input string + output types.Int + expectedErr bool + }{ + { + Int8Type, + "120", + 120, + false, + }, + { + Int16Type, + "30000", + 30000, + false, + }, + { + Int24Type, + "7000000", + 7000000, + false, + }, + { + Int32Type, + "2000000000", + 2000000000, + false, + }, + { + Int64Type, + strconv.FormatInt(math.MaxInt64, 10), + math.MaxInt64, + false, + }, + { + Int32Type, + "something", + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/set_test.go b/go/libraries/doltcore/schema/typeinfo/set_test.go new file mode 100644 index 0000000000..12bb7aeb27 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/set_test.go @@ -0,0 +1,43 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "testing" + + "github.com/src-d/go-mysql-server/sql" + "github.com/stretchr/testify/require" +) + +//TODO: add some basic tests once the storage format has been decided + +func generateSetTypes(t *testing.T, numOfTypes int64) []TypeInfo { + res := make([]TypeInfo, numOfTypes) + for i := int64(1); i <= numOfTypes; i++ { + res[i-1] = generateSetType(t, int(i)) + } + return res +} + +func generateSetType(t *testing.T, numOfElements int) *setType { + require.True(t, numOfElements >= 1 && numOfElements <= sql.SetTypeMaxElements) + vals := make([]string, numOfElements) + alphabet := "abcdefghijklmnopqrstuvwxyz" + lenAlphabet := len(alphabet) + for i := 0; i < numOfElements; i++ { + vals[i] = string([]byte{alphabet[(i/lenAlphabet)%lenAlphabet], alphabet[i%lenAlphabet]}) + } + return &setType{sql.MustCreateSetType(vals, sql.Collation_Default)} +} diff --git a/go/libraries/doltcore/schema/typeinfo/time_test.go b/go/libraries/doltcore/schema/typeinfo/time_test.go new file mode 100644 index 0000000000..798e01f95e --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/time_test.go @@ -0,0 +1,17 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +//TODO: add some basic tests once the storage format has been decided diff --git a/go/libraries/doltcore/schema/typeinfo/typeinfo_test.go b/go/libraries/doltcore/schema/typeinfo/typeinfo_test.go new file mode 100644 index 0000000000..ce14426ff8 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/typeinfo_test.go @@ -0,0 +1,381 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + "time" + + "github.com/src-d/go-mysql-server/sql" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestTypeInfoSuite(t *testing.T) { + typeInfoArrays, validTypeValues := generateTypeInfoArrays(t) + t.Run("VerifyArray", func(t *testing.T) { + verifyTypeInfoArrays(t, typeInfoArrays, validTypeValues) + }) + t.Run("ConvertRoundTrip", func(t *testing.T) { + testTypeInfoConvertRoundTrip(t, typeInfoArrays, validTypeValues) + }) + t.Run("Equals", func(t *testing.T) { + testTypeInfoEquals(t, typeInfoArrays) + }) + t.Run("ForeignKindHandling", func(t *testing.T) { + testTypeInfoForeignKindHandling(t, typeInfoArrays, validTypeValues) + }) + t.Run("FormatParseRoundTrip", func(t *testing.T) { + testTypeInfoFormatParseRoundTrip(t, typeInfoArrays, validTypeValues) + }) + t.Run("GetTypeParams", func(t *testing.T) { + testTypeInfoGetTypeParams(t, typeInfoArrays) + }) + t.Run("NullHandling", func(t *testing.T) { + testTypeInfoNullHandling(t, typeInfoArrays) + }) + t.Run("NomsKind", func(t *testing.T) { + testTypeInfoNomsKind(t, typeInfoArrays, validTypeValues) + }) + t.Run("ToSqlType", func(t *testing.T) { + testTypeInfoToSqlType(t, typeInfoArrays) + }) +} + +// verify that the TypeInfos and values are all consistent with each other, and cover the full range of types +func verifyTypeInfoArrays(t *testing.T, tiArrays [][]TypeInfo, vaArrays [][]types.Value) { + require.Equal(t, len(tiArrays), len(vaArrays)) + + seenTypeInfos := make(map[Identifier]bool) + for identifier := range Identifiers { + seenTypeInfos[identifier] = false + } + // delete any types that should not be tested + delete(seenTypeInfos, UnknownTypeIdentifier) + delete(seenTypeInfos, TupleTypeIdentifier) + for _, tiArray := range tiArrays { + // no row should be empty + require.True(t, len(tiArray) > 0, `length of array "%v" should be greater than zero`, len(tiArray)) + firstIdentifier := tiArray[0].GetTypeIdentifier() + t.Run(firstIdentifier.String(), func(t *testing.T) { + seen, ok := seenTypeInfos[firstIdentifier] + require.True(t, ok, `identifier "%v" is not recognized`, firstIdentifier) + require.False(t, seen, `identifier "%v" is used by another type from the array`, firstIdentifier) + seenTypeInfos[firstIdentifier] = true + for _, ti := range tiArray { + // verify that all of the types have the same identifier + require.Equal(t, firstIdentifier, ti.GetTypeIdentifier(), + `expected "%v" but got "%v"`, firstIdentifier, ti.GetTypeIdentifier()) + } + }) + } + // make sure that we are testing all of the types (unless deleted above) + for seenti, seen := range seenTypeInfos { + require.True(t, seen, `identifier "%v" does not have a relevant type being tested`, seenti) + } + for _, vaArray := range vaArrays { + // no row should be empty + require.True(t, len(vaArray) > 0, `length of array "%v" should be greater than zero`, len(vaArray)) + firstKind := vaArray[0].Kind() + for _, val := range vaArray { + // verify that all of the values in an row are of the same kind + require.Equal(t, firstKind, val.Kind(), `expected kind "%v" but got "%v"`, firstKind, val.Kind()) + } + } +} + +// assuming valid data, verifies that the To-From interface{} functions can round trip +func testTypeInfoConvertRoundTrip(t *testing.T, tiArrays [][]TypeInfo, vaArrays [][]types.Value) { + for rowIndex, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + //TODO: determine the storage format for DecimalType + //TODO: determine the storage format for VarBinaryType + if tiArray[0].GetTypeIdentifier() == DecimalTypeIdentifier || tiArray[0].GetTypeIdentifier() == VarBinaryTypeIdentifier { + t.Skipf(`"%v" not yet persisted, thus no need to fix tests`, tiArray[0].GetTypeIdentifier().String()) + } + for _, ti := range tiArray { + atLeastOneValid := false + t.Run(ti.String(), func(t *testing.T) { + for _, val := range vaArrays[rowIndex] { + t.Run(fmt.Sprintf(`types.%v(%v)`, val.Kind().String(), val.HumanReadableString()), func(t *testing.T) { + vInterface, err := ti.ConvertNomsValueToValue(val) + if ti.IsValid(val) { + atLeastOneValid = true + require.NoError(t, err) + outVal, err := ti.ConvertValueToNomsValue(vInterface) + require.NoError(t, err) + if ti == DateType { // Special case as DateType removes the hh:mm:ss + val = types.Timestamp(time.Time(val.(types.Timestamp)).Truncate(24 * time.Hour)) + require.True(t, val.Equals(outVal), "\"%v\"\n\"%v\"", val, outVal) + } else { + require.True(t, val.Equals(outVal), "\"%v\"\n\"%v\"", val, outVal) + } + } else { + assert.Error(t, err) + } + }) + } + }) + require.True(t, atLeastOneValid, `all values reported false for "%v"`, ti.String()) + } + }) + } +} + +// each TypeInfo in tiArrays is unique, so all equality comparisons should fail when the indices don't match +func testTypeInfoEquals(t *testing.T, tiArrays [][]TypeInfo) { + for tiArrayIndex, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + // check this TypeInfo against its own variations, EX: Int16 & Int32 + // a != b should also mean b != a + for i := range tiArray { + ti1 := tiArray[i] + t.Run(ti1.String(), func(t *testing.T) { + for j := range tiArray { + ti2 := tiArray[j] + t.Run(fmt.Sprintf(ti2.String()), func(t *testing.T) { + equality := ti1.Equals(ti2) + if i == j { + assert.True(t, equality) + } else { + assert.False(t, equality) + } + }) + } + }) + } + // we just check the first element and assume it'll hold true for the other values + firstTi := tiArray[0] + t.Run(fmt.Sprintf(`%v Others`, firstTi), func(t *testing.T) { + // check this TypeInfo against the other types, EX: Int16 & Float64 + for tiArrayIndex2, tiArray2 := range tiArrays { + if tiArrayIndex == tiArrayIndex2 { + // this is the for loop above + continue + } + for _, otherTi := range tiArray2 { + t.Run(fmt.Sprintf(otherTi.String()), func(t *testing.T) { + equality := firstTi.Equals(otherTi) + assert.False(t, equality) + }) + } + } + }) + }) + } +} + +// ConvertNomsValueToValue and FormatValue should fail if the kind does not match the TypeInfo kind +func testTypeInfoForeignKindHandling(t *testing.T, tiArrays [][]TypeInfo, vaArrays [][]types.Value) { + for _, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + for _, ti := range tiArray { + t.Run(ti.String(), func(t *testing.T) { + for _, vaArray := range vaArrays { + for _, val := range vaArray { + t.Run(fmt.Sprintf(`types.%v(%v)`, val.Kind().String(), val.HumanReadableString()), func(t *testing.T) { + if ti.NomsKind() != val.Kind() { + _, err := ti.ConvertNomsValueToValue(val) + assert.Error(t, err) + _, err = ti.FormatValue(val) + assert.Error(t, err) + } + }) + } + } + }) + } + }) + } +} + +// assuming valid data, verifies that the To-From string functions can round trip +func testTypeInfoFormatParseRoundTrip(t *testing.T, tiArrays [][]TypeInfo, vaArrays [][]types.Value) { + for rowIndex, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + //TODO: determine the storage format for DecimalType + //TODO: determine the storage format for VarBinaryType + if tiArray[0].GetTypeIdentifier() == DecimalTypeIdentifier || tiArray[0].GetTypeIdentifier() == VarBinaryTypeIdentifier { + t.Skipf(`"%v" not yet persisted, thus no need to fix tests`, tiArray[0].GetTypeIdentifier().String()) + } + for _, ti := range tiArray { + atLeastOneValid := false + t.Run(ti.String(), func(t *testing.T) { + for _, val := range vaArrays[rowIndex] { + t.Run(fmt.Sprintf(`types.%v(%v)`, val.Kind().String(), val.HumanReadableString()), func(t *testing.T) { + str, err := ti.FormatValue(val) + if ti.IsValid(val) { + atLeastOneValid = true + require.NoError(t, err) + outVal, err := ti.ParseValue(str) + require.NoError(t, err) + if ti == DateType { // special case as DateType removes the hh:mm:ss + val = types.Timestamp(time.Time(val.(types.Timestamp)).Truncate(24 * time.Hour)) + require.True(t, val.Equals(outVal), "\"%v\"\n\"%v\"", val, outVal) + } else { + require.True(t, val.Equals(outVal), "\"%v\"\n\"%v\"", val, outVal) + } + } else { + assert.Error(t, err) + } + }) + } + }) + require.True(t, atLeastOneValid, `all values reported false for "%v"`, ti.String()) + } + }) + } +} + +// verify that FromTypeParams can reconstruct the exact same TypeInfo from the params +func testTypeInfoGetTypeParams(t *testing.T, tiArrays [][]TypeInfo) { + for _, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + for _, ti := range tiArray { + t.Run(ti.String(), func(t *testing.T) { + newTi, err := FromTypeParams(ti.GetTypeIdentifier(), ti.GetTypeParams()) + require.NoError(t, err) + require.True(t, ti.Equals(newTi), "%v\n%v", ti.String(), newTi.String()) + }) + } + }) + } +} + +// makes sure that everything can handle nil and NullValue (if applicable) +func testTypeInfoNullHandling(t *testing.T, tiArrays [][]TypeInfo) { + for _, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + for _, ti := range tiArray { + t.Run(ti.String(), func(t *testing.T) { + t.Run("ConvertNomsValueToValue", func(t *testing.T) { + val, err := ti.ConvertNomsValueToValue(types.NullValue) + require.NoError(t, err) + require.Nil(t, val) + val, err = ti.ConvertNomsValueToValue(nil) + require.NoError(t, err) + require.Nil(t, val) + }) + t.Run("ConvertValueToNomsValue", func(t *testing.T) { + tVal, err := ti.ConvertValueToNomsValue(nil) + require.NoError(t, err) + require.Equal(t, types.NullValue, tVal) + }) + t.Run("FormatValue", func(t *testing.T) { + tVal, err := ti.FormatValue(types.NullValue) + require.NoError(t, err) + require.Nil(t, tVal) + tVal, err = ti.FormatValue(nil) + require.NoError(t, err) + require.Nil(t, tVal) + }) + t.Run("IsValid", func(t *testing.T) { + require.True(t, ti.IsValid(types.NullValue)) + require.True(t, ti.IsValid(nil)) + }) + t.Run("ParseValue", func(t *testing.T) { + tVal, err := ti.ParseValue(nil) + require.NoError(t, err) + require.Equal(t, types.NullValue, tVal) + }) + }) + } + }) + } +} + +// smoke test checking that the returned NomsKind is consistent and matches the values. +func testTypeInfoNomsKind(t *testing.T, tiArrays [][]TypeInfo, vaArrays [][]types.Value) { + for rowIndex, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + nomsKind := tiArray[0].NomsKind() + for _, ti := range tiArray { + t.Run("Equality "+ti.String(), func(t *testing.T) { + require.Equal(t, nomsKind, ti.NomsKind()) + }) + } + t.Run("Values "+tiArray[0].NomsKind().String(), func(t *testing.T) { + for _, val := range vaArrays[rowIndex] { + require.Equal(t, nomsKind, val.Kind()) + } + }) + }) + } +} + +// smoke test so that there are no obvious panics when returning SQL types +func testTypeInfoToSqlType(t *testing.T, tiArrays [][]TypeInfo) { + for _, tiArray := range tiArrays { + t.Run(tiArray[0].GetTypeIdentifier().String(), func(t *testing.T) { + for _, ti := range tiArray { + t.Run(ti.String(), func(t *testing.T) { + _ = ti.ToSqlType() + }) + } + }) + } +} + +// generate unique TypeInfos for each type, and also values that are valid for at least one of the TypeInfos for the matching row +func generateTypeInfoArrays(t *testing.T) ([][]TypeInfo, [][]types.Value) { + return [][]TypeInfo{ + generateBitTypes(t, 16), + {BoolType}, + {DateType, DatetimeType, TimestampType}, + generateDecimalTypes(t, 16), + generateEnumTypes(t, 16), + {Float32Type, Float64Type}, + {InlineBlobType}, + {Int8Type, Int16Type, Int24Type, Int32Type, Int64Type}, + generateSetTypes(t, 16), + {TimeType}, + {Uint8Type, Uint16Type, Uint24Type, Uint32Type, Uint64Type}, + {UuidType}, + append(generateVarBinaryTypes(t, 12), + &varBinaryType{sql.TinyBlob}, &varBinaryType{sql.Blob}, + &varBinaryType{sql.MediumBlob}, &varBinaryType{sql.LongBlob}), + append(generateVarStringTypes(t, 12), + &varStringType{sql.CreateTinyText(sql.Collation_Default)}, &varStringType{sql.CreateText(sql.Collation_Default)}, + &varStringType{sql.CreateMediumText(sql.Collation_Default)}, &varStringType{sql.CreateLongText(sql.Collation_Default)}), + {YearType}, + }, + [][]types.Value{ + {types.Uint(1), types.Uint(207), types.Uint(79147), types.Uint(34845728), types.Uint(9274618927)}, //Bit + {types.Bool(false), types.Bool(true)}, //Bool + {types.Timestamp(time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC)), //Datetime + types.Timestamp(time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC)), + types.Timestamp(time.Date(2000, 2, 28, 14, 38, 43, 583395000, time.UTC)), + types.Timestamp(time.Date(2038, 1, 19, 3, 14, 7, 999999000, time.UTC)), + types.Timestamp(time.Date(9999, 12, 31, 23, 59, 59, 999999000, time.UTC))}, + {types.String("1"), types.String("-1.5"), types.String("4723245"), //Decimal + types.String("8923583.125"), types.String("1198728394234798423466321.27349757")}, + {types.String("aaaa"), types.String("aaaa,aaac"), types.String("aaag"), types.String("aaab,aaad,aaaf"), types.String("aaag,aaah")}, //Enum + {types.Float(1.0), types.Float(65513.75), types.Float(4293902592), types.Float(4.58E71), types.Float(7.172E285)}, //Float + {types.InlineBlob{0}, types.InlineBlob{21}, types.InlineBlob{1, 17}, types.InlineBlob{72, 42}, types.InlineBlob{21, 122, 236}}, //InlineBlob + {types.Int(20), types.Int(215), types.Int(237493), types.Int(2035753568), types.Int(2384384576063)}, //Int + {types.String("aa"), types.String("aa,ac"), types.String("ag"), types.String("ab,ad,af"), types.String("ag,ah")}, //Set + {types.String("00:00:00"), types.String("00:00:01"), types.String("00:01:53"), types.String("68:36:59"), types.String("127:27:10.485214")}, //Time + {types.Uint(20), types.Uint(275), types.Uint(328395), types.Uint(630257298), types.Uint(93897259874)}, //Uint + {types.UUID{3}, types.UUID{3, 13}, types.UUID{128, 238, 82, 12}, types.UUID{31, 54, 23, 13, 63, 43}, types.UUID{83, 64, 21, 14, 42, 6, 35, 7, 54, 234, 6, 32, 1, 4, 2, 4}}, //Uuid + {types.String([]byte{1}), types.String([]byte{42, 52}), types.String([]byte{84, 32, 13, 63, 12, 86}), //VarBinary + types.String([]byte{1, 32, 235, 64, 32, 23, 45, 76}), types.String([]byte{123, 234, 34, 223, 76, 35, 32, 12, 84, 26, 15, 34, 65, 86, 45, 23, 43, 12, 76, 154, 234, 76, 34})}, + {types.String(""), types.String("a"), types.String("abc"), //VarString + types.String("abcdefghijklmnopqrstuvwxyz"), types.String("هذا هو بعض نماذج النص التي أستخدمها لاختبار عناصر")}, + {types.Int(1901), types.Int(1950), types.Int(2000), types.Int(2080), types.Int(2155)}, //Year + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/uint_test.go b/go/libraries/doltcore/schema/typeinfo/uint_test.go new file mode 100644 index 0000000000..6014820fb8 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/uint_test.go @@ -0,0 +1,271 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "math" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestUintConvertNomsValueToValue(t *testing.T) { + tests := []struct { + typ *uintType + input types.Uint + output interface{} + expectedErr bool + }{ + { + Uint8Type, + 120, + uint8(120), + false, + }, + { + Uint16Type, + 30000, + uint16(30000), + false, + }, + { + Uint24Type, + 7000000, + uint32(7000000), + false, + }, + { + Uint32Type, + 2000000000, + uint32(2000000000), + false, + }, + { + Uint64Type, + math.MaxInt64, + uint64(math.MaxInt64), + false, + }, + { + Uint32Type, + math.MaxUint64, + 0, + true, + }, + { + Uint24Type, + 1 << 25, + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestUintConvertValueToNomsValue(t *testing.T) { + tests := []struct { + typ *uintType + input interface{} + output types.Uint + expectedErr bool + }{ + { + Uint8Type, + true, + 1, + false, + }, + { + Uint16Type, + int16(25), + 25, + false, + }, + { + Uint24Type, + uint64(184035), + 184035, + false, + }, + { + Uint32Type, + float32(312.1235), + 312, + false, + }, + { + Uint64Type, + "184035", + 184035, + false, + }, + { + Uint24Type, + int32(math.MaxInt32), + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestUintFormatValue(t *testing.T) { + tests := []struct { + typ *uintType + input types.Uint + output string + expectedErr bool + }{ + { + Uint8Type, + 120, + "120", + false, + }, + { + Uint16Type, + 30000, + "30000", + false, + }, + { + Uint24Type, + 7000000, + "7000000", + false, + }, + { + Uint32Type, + 2000000000, + "2000000000", + false, + }, + { + Uint64Type, + math.MaxUint64, + strconv.FormatUint(math.MaxUint64, 10), + false, + }, + { + Uint32Type, + math.MaxUint64, + "", + true, + }, + { + Uint24Type, + 1 << 25, + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestUintParseValue(t *testing.T) { + tests := []struct { + typ *uintType + input string + output types.Uint + expectedErr bool + }{ + { + Uint8Type, + "120", + 120, + false, + }, + { + Uint16Type, + "30000", + 30000, + false, + }, + { + Uint24Type, + "7000000", + 7000000, + false, + }, + { + Uint32Type, + "2000000000", + 2000000000, + false, + }, + { + Uint64Type, + strconv.FormatInt(math.MaxInt64, 10), + math.MaxInt64, + false, + }, + { + Uint32Type, + "something", + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/uuid_test.go b/go/libraries/doltcore/schema/typeinfo/uuid_test.go new file mode 100644 index 0000000000..5999d1ab78 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/uuid_test.go @@ -0,0 +1,204 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestUuidConvertNomsValueToValue(t *testing.T) { + tests := []struct { + input types.UUID + output string + }{ + { + types.UUID(uuid.UUID{0}), + "00000000-0000-0000-0000-000000000000", + }, + { + types.UUID(uuid.UUID{1, 2, 3, 4}), + "01020304-0000-0000-0000-000000000000", + }, + { + types.UUID(uuid.UUID{11, 22, 33, 44, 55, 66, 77, 88, 99}), + "0b16212c-3742-4d58-6300-000000000000", + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, UuidType.String(), test.input), func(t *testing.T) { + output, err := UuidType.ConvertNomsValueToValue(test.input) + require.NoError(t, err) + require.Equal(t, test.output, output) + }) + } +} + +func TestUuidConvertValueToNomsValue(t *testing.T) { + tests := []struct { + input interface{} + output types.UUID + expectedErr bool + }{ + { + uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + types.UUID(uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), + false, + }, + { + "01020304-0506-0708-090a-0b0c0d0e0f10", + types.UUID(uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), + false, + }, + { + int8(1), + types.UUID{}, + true, + }, + { + int16(1), + types.UUID{}, + true, + }, + { + int32(1), + types.UUID{}, + true, + }, + { + int64(1), + types.UUID{}, + true, + }, + { + uint8(1), + types.UUID{}, + true, + }, + { + uint16(1), + types.UUID{}, + true, + }, + { + uint32(1), + types.UUID{}, + true, + }, + { + uint64(1), + types.UUID{}, + true, + }, + { + false, + types.UUID{}, + true, + }, + { + "something", + types.UUID{}, + true, + }, + { + "", + types.UUID{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, UuidType.String(), test.input), func(t *testing.T) { + output, err := UuidType.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output, "%v\n%v", test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestUuidFormatValue(t *testing.T) { + tests := []struct { + input types.UUID + output string + }{ + { + types.UUID(uuid.UUID{0}), + "00000000-0000-0000-0000-000000000000", + }, + { + types.UUID(uuid.UUID{1, 2, 3, 4}), + "01020304-0000-0000-0000-000000000000", + }, + { + types.UUID(uuid.UUID{11, 22, 33, 44, 55, 66, 77, 88, 99}), + "0b16212c-3742-4d58-6300-000000000000", + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, UuidType.String(), test.input), func(t *testing.T) { + output, err := UuidType.FormatValue(test.input) + require.NoError(t, err) + require.Equal(t, test.output, *output) + }) + } +} + +func TestUuidParseValue(t *testing.T) { + tests := []struct { + input string + output types.UUID + expectedErr bool + }{ + { + "01020304-0000-0000-0000-000000000000", + types.UUID(uuid.UUID{1, 2, 3, 4}), + false, + }, + { + "01020304-0506-0708-090a-0b0c0d0e0f10", + types.UUID(uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), + false, + }, + { + "something", + types.UUID{}, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, UuidType.String(), test.input), func(t *testing.T) { + output, err := UuidType.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/go/libraries/doltcore/schema/typeinfo/varbinary_test.go b/go/libraries/doltcore/schema/typeinfo/varbinary_test.go new file mode 100644 index 0000000000..0ef0fe0408 --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/varbinary_test.go @@ -0,0 +1,48 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "testing" + + "github.com/src-d/go-mysql-server/sql" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/sqltypes" +) + +//TODO: add some basic tests once the storage format has been decided + +func generateVarBinaryTypes(t *testing.T, numOfTypes uint16) []TypeInfo { + var res []TypeInfo + loop(t, 1, 500, numOfTypes, func(i int64) { + pad := false + if i%2 == 0 { + pad = true + } + res = append(res, generateVarBinaryType(t, i, pad)) + }) + return res +} + +func generateVarBinaryType(t *testing.T, length int64, pad bool) *varBinaryType { + require.True(t, length > 0) + if pad { + t, err := sql.CreateBinary(sqltypes.Binary, length) + if err == nil { + return &varBinaryType{t} + } + } + return &varBinaryType{sql.MustCreateBinary(sqltypes.VarBinary, length)} +} diff --git a/go/libraries/doltcore/schema/typeinfo/varstring_test.go b/go/libraries/doltcore/schema/typeinfo/varstring_test.go new file mode 100644 index 0000000000..9e682afbea --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/varstring_test.go @@ -0,0 +1,289 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + "time" + + "github.com/src-d/go-mysql-server/sql" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/sqltypes" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestVarStringConvertNomsValueToValue(t *testing.T) { + tests := []struct { + typ *varStringType + input types.String + output string + expectedErr bool + }{ + { + generateVarStringType(t, 10, false), + "0 ", + "0 ", + false, + }, + { + generateVarStringType(t, 10, true), + "0 ", + "0", + false, + }, + { + generateVarStringType(t, 80, false), + "this is some text that will be returned", + "this is some text that will be returned", + false, + }, + { + &varStringType{sql.CreateLongText(sql.Collation_Default)}, + " This is a sentence. ", + " This is a sentence. ", + false, + }, + { + generateVarStringType(t, 2, false), + "yay", + "", + true, + }, + { + generateVarStringType(t, 2, true), + "yey", + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestVarStringConvertValueToNomsValue(t *testing.T) { + tests := []struct { + typ *varStringType + input interface{} + output types.String + expectedErr bool + }{ + { + generateVarStringType(t, 10, false), + "0 ", + "0 ", + false, + }, + { + generateVarStringType(t, 10, true), + []byte("0 "), + "0 ", // converting to NomsValue counts as storage, thus we don't trim then + false, + }, + { + generateVarStringType(t, 80, false), + int64(28354), + "28354", + false, + }, + { + &varStringType{sql.CreateLongText(sql.Collation_Default)}, + float32(3724.75), + "3724.75", + false, + }, + { + generateVarStringType(t, 80, false), + time.Date(2030, 1, 2, 4, 6, 3, 472382485, time.UTC), + "2030-01-02 04:06:03.472382", + false, + }, + { + generateVarStringType(t, 2, true), + "yey", + "", + true, + }, + { + generateVarStringType(t, 2, true), + int32(382), + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestVarStringFormatValue(t *testing.T) { + tests := []struct { + typ *varStringType + input types.String + output string + expectedErr bool + }{ + { + generateVarStringType(t, 10, false), + "0 ", + "0 ", + false, + }, + { + generateVarStringType(t, 10, true), + "0 ", + "0", + false, + }, + { + generateVarStringType(t, 80, false), + "this is some text that will be returned", + "this is some text that will be returned", + false, + }, + { + &varStringType{sql.CreateLongText(sql.Collation_Default)}, + " This is a sentence. ", + " This is a sentence. ", + false, + }, + { + generateVarStringType(t, 2, false), + "yay", + "", + true, + }, + { + generateVarStringType(t, 2, true), + "yey", + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestVarStringParseValue(t *testing.T) { + tests := []struct { + typ *varStringType + input string + output types.String + expectedErr bool + }{ + { + generateVarStringType(t, 10, false), + "0 ", + "0 ", + false, + }, + { + generateVarStringType(t, 10, true), + "0 ", + "0 ", // converting to NomsValue counts as storage, thus we don't trim then + false, + }, + { + generateVarStringType(t, 80, false), + "this is some text that will be returned", + "this is some text that will be returned", + false, + }, + { + &varStringType{sql.CreateLongText(sql.Collation_Default)}, + " This is a sentence. ", + " This is a sentence. ", + false, + }, + { + generateVarStringType(t, 2, false), + "yay", + "", + true, + }, + { + generateVarStringType(t, 2, true), + "yey", + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, test.typ.String(), test.input), func(t *testing.T) { + output, err := test.typ.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func generateVarStringTypes(t *testing.T, numOfTypes uint16) []TypeInfo { + var res []TypeInfo + loop(t, 1, 500, numOfTypes, func(i int64) { + rts := false + if i%2 == 0 { + rts = true + } + res = append(res, generateVarStringType(t, i, rts)) + }) + return res +} + +func generateVarStringType(t *testing.T, length int64, rts bool) *varStringType { + require.True(t, length > 0) + if rts { + t, err := sql.CreateStringWithDefaults(sqltypes.Char, length) + if err == nil { + return &varStringType{t} + } + } + return &varStringType{sql.MustCreateStringWithDefaults(sqltypes.VarChar, length)} +} diff --git a/go/libraries/doltcore/schema/typeinfo/year_test.go b/go/libraries/doltcore/schema/typeinfo/year_test.go new file mode 100644 index 0000000000..921438142d --- /dev/null +++ b/go/libraries/doltcore/schema/typeinfo/year_test.go @@ -0,0 +1,210 @@ +// Copyright 2020 Liquidata, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package typeinfo + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/liquidata-inc/dolt/go/store/types" +) + +func TestYearConvertNomsValueToValue(t *testing.T) { + tests := []struct { + input types.Int + output int16 + expectedErr bool + }{ + { + 0, + 0, + false, + }, + { + 1901, + 1901, + false, + }, + { + 2000, + 2000, + false, + }, + { + 2155, + 2155, + false, + }, + { + 3000, + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, YearType.String(), test.input), func(t *testing.T) { + output, err := YearType.ConvertNomsValueToValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, output) + } + }) + } +} + +func TestYearConvertValueToNomsValue(t *testing.T) { + tests := []struct { + input interface{} + output types.Int + expectedErr bool + }{ + { + time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC), + 2001, + false, + }, + { + int8(70), + 1970, + false, + }, + { + uint64(89), + 1989, + false, + }, + { + "5", + 2005, + false, + }, + { + float32(7884.3), + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, YearType.String(), test.input), func(t *testing.T) { + output, err := YearType.ConvertValueToNomsValue(test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +} + +func TestYearFormatValue(t *testing.T) { + tests := []struct { + input types.Int + output string + expectedErr bool + }{ + { + 1, + "2001", + false, + }, + { + 1901, + "1901", + false, + }, + { + 2000, + "2000", + false, + }, + { + 89, + "1989", + false, + }, + { + 3000, + "", + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, YearType.String(), test.input), func(t *testing.T) { + output, err := YearType.FormatValue(test.input) + if test.expectedErr { + assert.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.output, *output) + } + }) + } +} + +func TestYearParseValue(t *testing.T) { + tests := []struct { + input string + output types.Int + expectedErr bool + }{ + { + "2001", + 2001, + false, + }, + { + "1901", + 1901, + false, + }, + { + "2000", + 2000, + false, + }, + { + "89", + 1989, + false, + }, + { + "3000", + 0, + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf(`%v %v`, YearType.String(), test.input), func(t *testing.T) { + output, err := YearType.ParseValue(&test.input) + if !test.expectedErr { + require.NoError(t, err) + assert.Equal(t, test.output, output) + } else { + assert.Error(t, err) + } + }) + } +}