Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 5B632431FAF for ; Sat, 28 Jul 2012 12:22:05 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nla4Ewd7y8rW for ; Sat, 28 Jul 2012 12:22:03 -0700 (PDT) Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU [18.7.68.37]) by olra.theworths.org (Postfix) with ESMTP id 0D33B431FAE for ; Sat, 28 Jul 2012 12:22:02 -0700 (PDT) X-AuditID: 12074425-b7f9b6d0000008c4-73-50143bda9f72 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP id D6.0E.02244.ADB34105; Sat, 28 Jul 2012 15:22:02 -0400 (EDT) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id q6SJM1DY001316; Sat, 28 Jul 2012 15:22:01 -0400 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q6SJLxtm000674 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sat, 28 Jul 2012 15:21:59 -0400 (EDT) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77) (envelope-from ) id 1SvCaM-0004Ta-S1; Sat, 28 Jul 2012 15:21:58 -0400 Date: Sat, 28 Jul 2012 15:21:58 -0400 From: Austin Clements To: Mark Walters Subject: Re: [PATCH v2 01/13] test: Uniformly canonicalize actual and expected JSON Message-ID: <20120728192158.GE8502@mit.edu> References: <1343449754-9010-1-git-send-email-amdragon@mit.edu> <1343449754-9010-2-git-send-email-amdragon@mit.edu> <87lii4uir2.fsf@qmul.ac.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <87lii4uir2.fsf@qmul.ac.uk> User-Agent: Mutt/1.5.21 (2010-09-15) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrEKsWRmVeSWpSXmKPExsUixG6nrnvLWiTAYMMXaYu9De2MFqvn8lhc vzmT2eLNynmsDiweO2fdZfdYvGk/m8fhrwtZPJ6tusUcwBLFZZOSmpNZllqkb5fAlfHlwVfW gq/nGSt6dl9ga2DcsZaxi5GTQ0LARGLt2x9MELaYxIV769lAbCGBfYwSE7e4dDFyAdkbGCXO HX/OAuGcZJJ4tuYnE4SzhFHixNa5YO0sAqoSF3sngtlsAhoS2/YvB1shIqAjcfvQAnYQm1nA XmLa2ROsILawQKhE787lQOs4OHgFtCWONEtCzJwMtHnfT7AaXgFBiZMzn7BA9OpI7Nx6B6ye WUBaYvk/DoiwvETz1tnMIDYn0Npd5z+BrRIVUJGYcnIb2wRG4VlIJs1CMmkWwqRZSCYtYGRZ xSibklulm5uYmVOcmqxbnJyYl5dapGuhl5tZopeaUrqJERwxLqo7GCccUjrEKMDBqMTDe+qK UIAQa2JZcWXuIUZJDiYlUd7P5iIBQnxJ+SmVGYnFGfFFpTmpxYcYJTiYlUR4rV8JBwjxpiRW VqUW5cOkpDlYlMR5b6Tc9BcSSE8sSc1OTS1ILYLJynBwKEnwcgATg5BgUWp6akVaZk4JQpqJ gxNkOA/Q8F8WQDW8xQWJucWZ6RD5U4zGHPefP7nNyHH78IvbjEIsefl5qVLivBetgEoFQEoz SvPgpsGS3itGcaDnhHllQZbyABMm3LxXQKuYgFZZRAuBrCpJREhJNTCeVUoOmKToeW/vpGBF obi64JP2rGUX+G4/vpJ5cUe/7qErr/wCDDl5Dvq87ynfo335mkRg5af8xWL7+gorF9V7la1h +r39YkYCw2Kf1RLNhwpsV7uHBvNwp/By1dYxBW9+sEmh/2Sh4uP8BO5PUypfc06+N8/k898l Np51U9Vj0pKEhUye7FViKc5INNRiLipOBAAfJ1STVQMAAA== Cc: tomi.ollila@iki.fi, notmuch@notmuchmail.org X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Jul 2012 19:22:05 -0000 Quoth Mark Walters on Jul 28 at 2:18 pm: > > 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 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 ", > > "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 ", > > "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 ", > > "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 ", > > "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 ", > > "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 ", > > "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 ", > > "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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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? Yes, that's a good idea. I'd rather do that in a follow-up patch that cleans up all of the expected JSON output, since even the stuff that is wrapped is wrapped strangely and not indented. > > # 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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"To\": \"Notmuch Test Suite \", \"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 \", \"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 \", \"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 ", > > "To": "Notmuch Test Suite ", > > -"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 <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 <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 <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 <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 <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 <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 <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 <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 <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 <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 <EXPECTED > > {"reply-headers": {"Subject": "Re: Multipart message", > > "From": "Notmuch Test Suite ", > > - "To": "Carl Worth , > > - cworth@cworth.org", > > + "To": "Carl Worth , 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 <EXPECTED > > "headers": {"Subject": "Multipart message", > > "From": "Carl Worth ", > > "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 <EXPECTED > > "content": [{"headers": {"Subject": "html message", > > "From": "Carl Worth ", > > "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 <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 <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