unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
blob afc19f4b044729a37a7e004cc6bae500611b9943 3212 bytes (raw)
name: test/json_check_nodes.py 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
#!/usr/bin/env python
import re
import sys
import json


EXPR_RE = re.compile('(?P<label>[a-zA-Z0-9_-]+):(?P<address>[^=!]+)(?:(?P<type>[=!])(?P<val>.*))?', re.DOTALL|re.MULTILINE)


if len(sys.argv) < 2:
    sys.exit('usage: '+ sys.argv[0] + """ EXPR [EXPR]

Takes json data on stdin and evaluates test expressions specified in
arguments.  Each test is evaluated, and output is printed only if the
test fails.  If any test fails the return value of execution will be
non-zero.

EXPR can be one of following types:

Value test: test that object in json data found at address is equal to specified value:

  label:address|value

Existence test: test that dict or list in json data found at address
does *not* contain the specified key:

  label:address!key

Extract: extract object from json data found at address and print

  label:address

Results are printed to stdout prefixed by expression label.  In all
cases the test will fail if object does not exist in data.

Example:

0 $ echo '["a", "b", {"c": 1}]' | python3 json_check_nodes.py 'second_d:[1]="d"' 'no_c:[2]!"c"'
second_d: value not equal: data[1] = 'b' != 'd'
no_c: dict contains key: data[2]["c"] = "c"
1 $

""")


# parse expressions from arguments
exprs = []
for expr in sys.argv[1:]:
    m = re.match(EXPR_RE, expr)
    if not m:
        sys.exit("Invalid expression: {}".format(expr))
    exprs.append(m)

data = json.load(sys.stdin)

fail = False

for expr in exprs:
    # print(expr.groups(),fail)

    e = 'data{}'.format(expr.group('address'))
    try:
        val = eval(e)
    except SyntaxError:
        fail = True
        print("{}: syntax error on evaluation of object: {}".format(
            expr.group('label'), e))
        continue
    except:
        fail = True
        print("{}: object not found: data{}".format(
            expr.group('label'), expr.group('address')))
        continue

    if expr.group('type') == '=':
        try:
            obj_val = json.loads(expr.group('val'))
        except:
            fail = True
            print("{}: error evaluating value: {}".format(
                expr.group('label'), expr.group('address')))
            continue
        if val != obj_val:
            fail = True
            print("{}: value not equal: data{} = {} != {}".format(
                expr.group('label'), expr.group('address'), repr(val), repr(obj_val)))

    elif expr.group('type') == '!':
        if not isinstance(val, (dict, list)):
            fail = True
            print("{}: not a dict or a list: data{}".format(
                expr.group('label'), expr.group('address')))
            continue
        try:
            idx = json.loads(expr.group('val'))
            if idx in val:
                fail = True
                print("{}: {} contains key: {}[{}] = {}".format(
                    expr.group('label'), type(val), e, expr.group('val'), val[idx]))
        except SyntaxError:
            fail = True
            print("{}: syntax error on evaluation of value: {}".format(
                expr.group('label'), expr.group('val')))
            continue


    elif expr.group('type') is None:
        print("{}: {}".format(expr.group('label'), val))


if fail:
    sys.exit(1)
sys.exit(0)

debug log:

solving afc19f4b ...
found afc19f4b in https://yhetil.org/notmuch/20190526221610.2833-4-dkg@fifthhorseman.net/

applying [1/1] https://yhetil.org/notmuch/20190526221610.2833-4-dkg@fifthhorseman.net/
diff --git a/test/json_check_nodes.py b/test/json_check_nodes.py
new file mode 100755
index 00000000..afc19f4b

Checking patch test/json_check_nodes.py...
Applied patch test/json_check_nodes.py cleanly.

index at:
100755 afc19f4b044729a37a7e004cc6bae500611b9943	test/json_check_nodes.py

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).