55 lines
1.9 KiB
Python
55 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Enumerate the DISTINCT contract violations (type + message) found by the sweep."""
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
ENGINE = os.path.join(HERE, "jsonptr_patch.py")
|
|
sys.path.insert(0, HERE)
|
|
import jsonptr_patch as E # noqa: E402
|
|
|
|
WEIRD = ["\u00b2", "\u00b3", "\u00b9", "\u2070", "\u0661", "\u0662", "\u0660",
|
|
"\u06f1", "\uff11", "\U0001d7d9", "\U0001d7da", "\u00bd", "\u2153",
|
|
"1e0", "-0", "+0", "01", "0x1", " 1", "1 ", "0b1", "1_0",
|
|
"~", "~2", "~01", "~10", "~00", "~11", "", "-", "0", "00",
|
|
"\u0000", "\n", "\t", "a/b", "a~b", "%20", "\u200b"]
|
|
DOCS = [{}, [], [1, 2, 3], {"a": 1, "b": {"c": 2}},
|
|
{"\u00b2": "k"}, {"a": [10, 20]}, {"a": {"b": [{"c": 1}]}}]
|
|
OPS = ["add", "remove", "replace", "move", "copy", "test"]
|
|
CONTRACT = (E.JsonPatchError, E.JsonPointerError)
|
|
|
|
found = {}
|
|
n = 0
|
|
for doc in DOCS:
|
|
for tok in WEIRD:
|
|
ref = "/" + tok
|
|
for op in OPS:
|
|
patch = [{"op": op, "path": ref}]
|
|
if op in ("add", "replace", "test"):
|
|
patch[0]["value"] = 1
|
|
if op in ("move", "copy"):
|
|
patch[0]["from"] = ref
|
|
n += 1
|
|
try:
|
|
E.apply_patch(doc, patch)
|
|
except CONTRACT:
|
|
pass
|
|
except Exception as exc: # noqa: BLE001
|
|
found.setdefault((type(exc).__name__, str(exc)),
|
|
(doc, ref, op))
|
|
|
|
print("calls=%d distinct violations=%d" % (n, len(found)))
|
|
for (tname, msg), (doc, ref, op) in sorted(found.items()):
|
|
print(" %-12s %s" % (tname, msg))
|
|
print(" e.g. doc=%r op=%s path=%r" % (doc, op, ref))
|
|
|
|
# Which ops surface it?
|
|
print()
|
|
ops_seen = {}
|
|
for (tname, msg), (doc, ref, op) in found.items():
|
|
ops_seen.setdefault(tname, set()).add(op)
|
|
for tname, ops in ops_seen.items():
|
|
print("%s surfaces via ops: %s" % (tname, sorted(ops)))
|