|
| 1 | +# Patchwork - automated patch tracking system |
| 2 | +# Copyright (C) 2018 Stephen Finucane <[email protected]> |
| 3 | +# |
| 4 | +# SPDX-License-Identifier: GPL-2.0-or-later |
| 5 | + |
| 6 | +import functools |
| 7 | +import json |
| 8 | +import os |
| 9 | + |
| 10 | +# docs/examples |
| 11 | +OUT_DIR = os.path.join( |
| 12 | + os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir, |
| 13 | + os.pardir, 'docs', 'api', 'samples') |
| 14 | + |
| 15 | +_WRITTEN_FILES = {} |
| 16 | + |
| 17 | + |
| 18 | +def _duplicate_sample(filename, func): |
| 19 | + global _WRITTEN_FILES |
| 20 | + |
| 21 | + # sanity check to make sure we're not writing to the same file |
| 22 | + # twice |
| 23 | + if filename in _WRITTEN_FILES: |
| 24 | + # though if tests do this, we simply ignore subsequent |
| 25 | + # writes |
| 26 | + if _WRITTEN_FILES[filename] == func: |
| 27 | + return True |
| 28 | + |
| 29 | + raise Exception( |
| 30 | + "Tests '{}' and '{}' write to the same file".format( |
| 31 | + _WRITTEN_FILES[filename], func)) |
| 32 | + |
| 33 | + _WRITTEN_FILES[filename] = func |
| 34 | + |
| 35 | + return False |
| 36 | + |
| 37 | + |
| 38 | +def store_samples(filename): |
| 39 | + """Wrapper to store responses and requests generated in tests. |
| 40 | +
|
| 41 | + These can be used in documentation. Only the first response or request body |
| 42 | + is saved per test. |
| 43 | + """ |
| 44 | + |
| 45 | + if not os.path.exists(OUT_DIR): |
| 46 | + os.mkdir(OUT_DIR) |
| 47 | + |
| 48 | + def inner(func): |
| 49 | + |
| 50 | + def wrapper(self, *args, **kwargs): |
| 51 | + |
| 52 | + def client_wrapper(orig_func, path, data=None, *orig_args, |
| 53 | + **orig_kwargs): |
| 54 | + |
| 55 | + req_filename = filename + '-req.json' |
| 56 | + resp_filename = filename + '-resp.json' |
| 57 | + |
| 58 | + # we don't have a request body for GET requests |
| 59 | + if orig_func != _get and not _duplicate_sample( |
| 60 | + req_filename, func): |
| 61 | + with open(os.path.join(OUT_DIR, req_filename), 'w') as fh: |
| 62 | + json.dump(data, fh, indent=4, separators=(',', ': ')) |
| 63 | + |
| 64 | + resp = orig_func(path, data, *orig_args, **orig_kwargs) |
| 65 | + |
| 66 | + if not _duplicate_sample(resp_filename, func): |
| 67 | + with open(os.path.join(OUT_DIR, resp_filename), 'w') as fh: |
| 68 | + json.dump(resp.data, fh, indent=4, |
| 69 | + separators=(',', ': ')) |
| 70 | + |
| 71 | + return resp |
| 72 | + |
| 73 | + # replace client.* with our own implementations |
| 74 | + _get = self.client.get |
| 75 | + self.client.get = functools.partial(client_wrapper, _get) |
| 76 | + _post = self.client.post |
| 77 | + self.client.post = functools.partial(client_wrapper, _post) |
| 78 | + _put = self.client.put |
| 79 | + self.client.put = functools.partial(client_wrapper, _put) |
| 80 | + _patch = self.client.patch |
| 81 | + self.client.patch = functools.partial(client_wrapper, _patch) |
| 82 | + |
| 83 | + func(self, *args, **kwargs) |
| 84 | + |
| 85 | + # ...then reverse |
| 86 | + self.client.patch = _patch |
| 87 | + self.client.put = _put |
| 88 | + self.client.post = _post |
| 89 | + self.client.get = _get |
| 90 | + |
| 91 | + return wrapper |
| 92 | + |
| 93 | + return inner |
0 commit comments