This looks good to me. I have read the test patches too now and they look fine. I just have one possible thought (see below) which is definitely not worth holding up this series for. Best wishes Mark On Sat, 28 Jul 2012, Austin Clements <amdragon@MIT.EDU> wrote: > Previously, we used a variety of ad-hoc canonicalizations for JSON > output in the test suite, but were ultimately very sensitive to JSON > irrelevancies such as whitespace. This introduces a new test > comparison function, test_expect_equal_json, that first pretty-prints > *both* the actual and expected JSON and the compares the result. > > The current implementation of this simply uses Python's json.tool to > perform pretty-printing (with a fallback to the identity function if > parsing fails). However, since the interface it introduces is > semantically high-level, we could swap in other mechanisms in the > future, such as another pretty-printer or something that does not > re-order object keys (if we decide that we care about that). > > In general, this patch does not remove the existing ad-hoc > canonicalization because it does no harm. We do have to remove the > newline-after-comma rule from notmuch_json_show_sanitize and > filter_show_json because it results in invalid JSON that cannot be > pretty-printed. > > Most of this patch simply replaces test_expect_equal and > test_expect_equal_file with test_expect_equal_json. It changes the > expected JSON in a few places where sanitizers had placed newlines > after commas inside strings. > --- > test/crypto | 37 +++++++++++++++---------------------- > test/json | 14 +++++++------- > test/maildir-sync | 11 ++++------- > test/multipart | 34 +++++++++++++++------------------- > test/search-output | 2 +- > test/test-lib.sh | 17 +++++++++++++---- > 6 files changed, 55 insertions(+), 60 deletions(-) > > diff --git a/test/crypto b/test/crypto > index be752b1..5dd14c4 100755 > --- a/test/crypto > +++ b/test/crypto > @@ -51,8 +51,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test signed message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "sigstatus": [{"status": "good", > "fingerprint": "'$FINGERPRINT'", > @@ -64,7 +63,7 @@ expected='[[[{"id": "XXXXX", > {"id": 3, > "content-type": "application/pgp-signature"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > @@ -85,8 +84,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test signed message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "sigstatus": [{"status": "good", > "fingerprint": "'$FINGERPRINT'", > @@ -99,7 +97,7 @@ expected='[[[{"id": "XXXXX", > {"id": 3, > "content-type": "application/pgp-signature"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > @@ -119,8 +117,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test signed message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "sigstatus": [{"status": "error", > "keyid": "'$(echo $FINGERPRINT | cut -c 25-)'", > @@ -132,7 +129,7 @@ expected='[[[{"id": "XXXXX", > {"id": 3, > "content-type": "application/pgp-signature"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > mv "${GNUPGHOME}"{.bak,} > @@ -193,8 +190,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test encrypted message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "encstatus": [{"status": "good"}], > "sigstatus": [], > @@ -210,7 +206,7 @@ expected='[[[{"id": "XXXXX", > "content-type": "application/octet-stream", > "filename": "TESTATTACHMENT"}]}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > @@ -221,7 +217,7 @@ output=$(notmuch show --format=json --part=4 --decrypt subject:"test encrypted m > expected='{"id": 4, > "content-type": "text/plain", > "content": "This is a test encrypted message.\n"}' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > @@ -248,8 +244,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test encrypted message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "encstatus": [{"status": "bad"}], > "content-type": "multipart/encrypted", > @@ -258,7 +253,7 @@ expected='[[[{"id": "XXXXX", > {"id": 3, > "content-type": "application/octet-stream"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > mv "${GNUPGHOME}"{.bak,} > @@ -283,8 +278,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test encrypted message 002", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "encstatus": [{"status": "good"}], > "sigstatus": [{"status": "good", > @@ -298,7 +292,7 @@ expected='[[[{"id": "XXXXX", > "content-type": "text/plain", > "content": "This is another test encrypted message.\n"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > @@ -338,8 +332,7 @@ expected='[[[{"id": "XXXXX", > "headers": {"Subject": "test signed message 001", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "test_suite@notmuchmail.org", > - "Date": "Sat, > - 01 Jan 2000 12:00:00 +0000"}, > + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, > "body": [{"id": 1, > "sigstatus": [{"status": "error", > "keyid": "6D92612D94E46381", > @@ -351,7 +344,7 @@ expected='[[[{"id": "XXXXX", > {"id": 3, > "content-type": "application/pgp-signature"}]}]}, > []]]]' > -test_expect_equal \ > +test_expect_equal_json \ > "$output" \ > "$expected" > > diff --git a/test/json b/test/json > index 831e105..d86ee46 100755 > --- a/test/json > +++ b/test/json > @@ -5,21 +5,21 @@ test_description="--format=json output" > test_begin_subtest "Show message: json" > add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-show-message\"" > output=$(notmuch show --format=json "json-show-message") > -test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" > +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" Since test_expect_equal_json does not care about whitespace (outside of strings) would it be worth splitting the expected output for each of these tests into multiple lines? > # This should be the same output as above. > test_begin_subtest "Show message: json --body=true" > output=$(notmuch show --format=json --body=true "json-show-message") > -test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" > +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" > > test_begin_subtest "Show message: json --body=false" > output=$(notmuch show --format=json --body=false "json-show-message") > -test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}}, []]]]" > +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}}, []]]]" > > test_begin_subtest "Search message: json" > add_message "[subject]=\"json-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-search-message\"" > output=$(notmuch search --format=json "json-search-message" | notmuch_json_show_sanitize | notmuch_search_sanitize) > -test_expect_equal "$output" "[{\"thread\": \"XXX\", > +test_expect_equal_json "$output" "[{\"thread\": \"XXX\", > \"timestamp\": 946728000, > \"date_relative\": \"2000-01-01\", > \"matched\": 1, > @@ -32,7 +32,7 @@ test_expect_equal "$output" "[{\"thread\": \"XXX\", > test_begin_subtest "Show message: json, utf-8" > add_message "[subject]=\"json-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\"" > output=$(notmuch show --format=json "jsön-show-méssage") > -test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]" > +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]" > > test_begin_subtest "Show message: json, inline attachment filename" > subject='json-show-inline-attachment-filename' > @@ -45,12 +45,12 @@ emacs_deliver_message \ > (insert \"Message-ID: <$id>\n\")" > output=$(notmuch show --format=json "id:$id") > filename=$(notmuch search --output=files "id:$id") > -test_expect_equal "$output" "[[[{\"id\": \"$id\", \"match\": true, \"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"filename\": \"README\"}]}]}, []]]]" > +test_expect_equal_json "$output" "[[[{\"id\": \"$id\", \"match\": true, \"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite <test_suite@notmuchmail.org>\", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"filename\": \"README\"}]}]}, []]]]" > > test_begin_subtest "Search message: json, utf-8" > add_message "[subject]=\"json-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\"" > output=$(notmuch search --format=json "jsön-search-méssage" | notmuch_json_show_sanitize | notmuch_search_sanitize) > -test_expect_equal "$output" "[{\"thread\": \"XXX\", > +test_expect_equal_json "$output" "[{\"thread\": \"XXX\", > \"timestamp\": 946728000, > \"date_relative\": \"2000-01-01\", > \"matched\": 1, > diff --git a/test/maildir-sync b/test/maildir-sync > index 01348d3..b748d04 100755 > --- a/test/maildir-sync > +++ b/test/maildir-sync > @@ -4,11 +4,9 @@ test_description="maildir synchronization" > > . ./test-lib.sh > > -# Much easier to examine differences if the "notmuch show > -# --format=json" output includes some newlines. Also, need to avoid > -# including the local value of MAIL_DIR in the result. > +# Avoid including the local value of MAIL_DIR in the result. > filter_show_json() { > - sed -e 's/, /,\n/g' | sed -e "s|${MAIL_DIR}/|MAIL_DIR/|" > + sed -e "s|${MAIL_DIR}/|MAIL_DIR/|" > echo > } > > @@ -44,7 +42,7 @@ test_expect_equal "$output" "adding-replied-tag:2,RS" > > test_begin_subtest "notmuch show works with renamed file (without notmuch new)" > output=$(notmuch show --format=json id:${gen_msg_id} | filter_show_json) > -test_expect_equal "$output" '[[[{"id": "adding-replied-tag@notmuch-test-suite", > +test_expect_equal_json "$output" '[[[{"id": "adding-replied-tag@notmuch-test-suite", > "match": true, > "excluded": false, > "filename": "MAIL_DIR/cur/adding-replied-tag:2,RS", > @@ -54,8 +52,7 @@ test_expect_equal "$output" '[[[{"id": "adding-replied-tag@notmuch-test-suite", > "headers": {"Subject": "Adding replied tag", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > "To": "Notmuch Test Suite <test_suite@notmuchmail.org>", > -"Date": "Fri, > -05 Jan 2001 15:43:57 +0000"}, > +"Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, > "body": [{"id": 1, > "content-type": "text/plain", > "content": "This is just a test message (#3)\n"}]}, > diff --git a/test/multipart b/test/multipart > index 72d3927..3ccf27f 100755 > --- a/test/multipart > +++ b/test/multipart > @@ -334,7 +334,7 @@ cat <<EOF >EXPECTED > {"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, > {"id": 9, "content-type": "application/pgp-signature"}]}]} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=1, message body" > notmuch show --format=json --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -351,7 +351,7 @@ cat <<EOF >EXPECTED > {"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, > {"id": 9, "content-type": "application/pgp-signature"}]} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=2, multipart/mixed" > notmuch show --format=json --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -366,7 +366,7 @@ cat <<EOF >EXPECTED > {"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, > {"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=3, rfc822 part" > notmuch show --format=json --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -378,7 +378,7 @@ cat <<EOF >EXPECTED > {"id": 5, "content-type": "text/html"}, > {"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=4, rfc822's multipart/alternative" > notmuch show --format=json --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -389,7 +389,7 @@ cat <<EOF >EXPECTED > {"id": 5, "content-type": "text/html"}, > {"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=5, rfc822's html part" > notmuch show --format=json --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -398,7 +398,7 @@ cat <<EOF >EXPECTED > > {"id": 5, "content-type": "text/html"} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=6, rfc822's text part" > notmuch show --format=json --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -407,7 +407,7 @@ cat <<EOF >EXPECTED > > {"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=7, inline attachment" > notmuch show --format=json --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -416,7 +416,7 @@ cat <<EOF >EXPECTED > > {"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=8, plain text part" > notmuch show --format=json --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -425,7 +425,7 @@ cat <<EOF >EXPECTED > > {"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--format=json --part=9, pgp signature (unverified)" > notmuch show --format=json --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' | sed 's|{"id":|\n{"id":|g' >OUTPUT > @@ -434,7 +434,7 @@ cat <<EOF >EXPECTED > > {"id": 9, "content-type": "application/pgp-signature"} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_expect_success \ > "--format=json --part=10, no part, expect error" \ > @@ -617,8 +617,7 @@ notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_j > cat <<EOF >EXPECTED > {"reply-headers": {"Subject": "Re: Multipart message", > "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", > - "To": "Carl Worth <cworth@cworth.org>, > - cworth@cworth.org", > + "To": "Carl Worth <cworth@cworth.org>, cworth@cworth.org", > "In-reply-to": "<87liy5ap00.fsf@yoom.home.cworth.org>", > "References": " <87liy5ap00.fsf@yoom.home.cworth.org>"}, > "original": {"id": "XXXXX", > @@ -631,8 +630,7 @@ cat <<EOF >EXPECTED > "headers": {"Subject": "Multipart message", > "From": "Carl Worth <cworth@cworth.org>", > "To": "cworth@cworth.org", > - "Date": "Fri, > - 05 Jan 2001 15:43:57 +0000"}, > + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, > "body": [{"id": 1, > "content-type": "multipart/signed", > "content": [{"id": 2, > @@ -642,16 +640,14 @@ cat <<EOF >EXPECTED > "content": [{"headers": {"Subject": "html message", > "From": "Carl Worth <cworth@cworth.org>", > "To": "cworth@cworth.org", > - "Date": "Fri, > - 05 Jan 2001 15:42:57 +0000"}, > + "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, > "body": [{"id": 4, > "content-type": "multipart/alternative", > "content": [{"id": 5, > "content-type": "text/html"}, > {"id": 6, > "content-type": "text/plain", > - "content": "This is an embedded message, > - with a multipart/alternative part.\n"}]}]}]}, > + "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, > {"id": 7, > "content-type": "text/plain", > "filename": "YYYYY", > @@ -662,7 +658,7 @@ cat <<EOF >EXPECTED > {"id": 9, > "content-type": "application/pgp-signature"}]}]}} > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF pair" > notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out > diff --git a/test/search-output b/test/search-output > index 8b57a43..c2a87eb 100755 > --- a/test/search-output > +++ b/test/search-output > @@ -62,7 +62,7 @@ cat <<EOF >EXPECTED > "THREADID", > "THREADID"] > EOF > -test_expect_equal_file OUTPUT EXPECTED > +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" > > test_begin_subtest "--output=messages" > notmuch search --output=messages '*' >OUTPUT > diff --git a/test/test-lib.sh b/test/test-lib.sh > index 06aaea2..791d2dc 100644 > --- a/test/test-lib.sh > +++ b/test/test-lib.sh > @@ -512,6 +512,16 @@ test_expect_equal_file () > fi > } > > +# Like test_expect_equal, but arguments are JSON expressions to be > +# canonicalized before diff'ing. If an argument cannot be parsed, it > +# is used unchanged so that there's something to diff against. > +test_expect_equal_json () { > + output=$(echo "$1" | python -mjson.tool || echo "$1") > + expected=$(echo "$2" | python -mjson.tool || echo "$2") > + shift 2 > + test_expect_equal "$output" "$expected" "$@" > +} > + > test_emacs_expect_t () { > test "$#" = 2 && { prereq=$1; shift; } || prereq= > test "$#" = 1 || > @@ -565,10 +575,9 @@ notmuch_show_sanitize_all () > > notmuch_json_show_sanitize () > { > - sed -e 's|, |,\n |g' | \ > - sed \ > - -e 's|"id": "[^"]*",|"id": "XXXXX",|' \ > - -e 's|"filename": "[^"]*",|"filename": "YYYYY",|' > + sed \ > + -e 's|"id": "[^"]*",|"id": "XXXXX",|g' \ > + -e 's|"filename": "[^"]*",|"filename": "YYYYY",|g' > } > > # End of notmuch helper functions > -- > 1.7.10