OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import difflib |
| 6 import json |
| 7 import os |
| 8 import pprint |
| 9 |
| 10 try: |
| 11 import yaml # pylint: disable=F0401 |
| 12 except ImportError: |
| 13 yaml = None |
| 14 |
| 15 |
| 16 NonExistant = object() |
| 17 |
| 18 |
| 19 SUPPORTED_SERIALIZERS = {'json', 'yaml'} |
| 20 SERIALIZERS = {} |
| 21 |
| 22 |
| 23 # JSON support |
| 24 def re_encode(obj): |
| 25 if isinstance(obj, dict): |
| 26 return {re_encode(k): re_encode(v) for k, v in obj.iteritems()} |
| 27 elif isinstance(obj, list): |
| 28 return [re_encode(i) for i in obj] |
| 29 elif isinstance(obj, unicode): |
| 30 return obj.encode('utf-8') |
| 31 else: |
| 32 return obj |
| 33 |
| 34 |
| 35 SERIALIZERS['json'] = ( |
| 36 lambda s: re_encode(json.load(s)), |
| 37 lambda data, stream: json.dump( |
| 38 data, stream, sort_keys=True, indent=2, separators=(',', ': '))) |
| 39 |
| 40 |
| 41 # YAML support |
| 42 if yaml: |
| 43 _YAMLSafeLoader = getattr(yaml, 'CSafeLoader', yaml.SafeLoader) |
| 44 _YAMLSafeDumper = getattr(yaml, 'CSafeDumper', yaml.SafeDumper) |
| 45 SERIALIZERS['yaml'] = ( |
| 46 lambda stream: yaml.load(stream, _YAMLSafeLoader), |
| 47 lambda data, stream: yaml.dump( |
| 48 data, stream, _YAMLSafeDumper, default_flow_style=False, |
| 49 encoding='utf-8')) |
| 50 |
| 51 |
| 52 def GetCurrentData(test): |
| 53 """ |
| 54 @type test: Test() |
| 55 @returns: The deserialized data (or NonExistant), and a boolean indicating if |
| 56 the current serialized data is in the same format which was |
| 57 requested by |test|. |
| 58 @rtype: (dict, bool) |
| 59 """ |
| 60 for ext in sorted(SUPPORTED_SERIALIZERS, key=lambda s: s != test.ext): |
| 61 path = test.expect_path(ext) |
| 62 if ext not in SERIALIZERS: |
| 63 raise Exception('The package to support %s is not installed.' % ext) |
| 64 if os.path.exists(path): |
| 65 with open(path, 'rb') as f: |
| 66 data = SERIALIZERS[ext][0](f) |
| 67 return data, ext == test.ext |
| 68 return NonExistant, True |
| 69 |
| 70 |
| 71 def WriteNewData(test, data): |
| 72 """ |
| 73 @type test: Test() |
| 74 """ |
| 75 if test.ext not in SUPPORTED_SERIALIZERS: |
| 76 raise Exception('%s is not a supported serializer.' % test.ext) |
| 77 if test.ext not in SERIALIZERS: |
| 78 raise Exception('The package to support %s is not installed.' % test.ext) |
| 79 with open(test.expect_path(), 'wb') as f: |
| 80 SERIALIZERS[test.ext][1](data, f) |
| 81 |
| 82 |
| 83 def DiffData(old, new): |
| 84 """ |
| 85 Takes old data and new data, then returns a textual diff as a list of lines. |
| 86 @type old: dict |
| 87 @type new: dict |
| 88 @rtype: [str] |
| 89 """ |
| 90 if old is NonExistant: |
| 91 return new |
| 92 if old == new: |
| 93 return None |
| 94 else: |
| 95 return list(difflib.context_diff( |
| 96 pprint.pformat(old).splitlines(), |
| 97 pprint.pformat(new).splitlines(), |
| 98 fromfile='expected', tofile='current', |
| 99 n=4, lineterm='' |
| 100 )) |
OLD | NEW |