Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: tests/test_packagerWebExt.py

Issue 29586561: Noissue - Make comparable_xml safe against ambiguous tags (Closed)
Patch Set: Addressing Vasily's comments Created Oct. 23, 2017, 1:19 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import difflib 5 import difflib
6 import json 6 import json
7 import os 7 import os
8 import re 8 import re
9 import shutil 9 import shutil
10 import zipfile 10 import zipfile
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 files['ext/c.js'] = 'var this_is_c;' 233 files['ext/c.js'] = 'var this_is_c;'
234 234
235 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js']) 235 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js'])
236 ext_dir = tmpdir.mkdir('ext') 236 ext_dir = tmpdir.mkdir('ext')
237 ext_dir.join('a.js').write(files['ext/a.js']) 237 ext_dir.join('a.js').write(files['ext/a.js'])
238 ext_dir.join('c.js').write(files['ext/c.js']) 238 ext_dir.join('c.js').write(files['ext/c.js'])
239 239
240 return files 240 return files
241 241
242 242
243 def comparable_xml(xml): 243 def comparable_json(json_data):
244 """Create a nonambiguous representation of a given XML tree. 244 """Create a nonambiguous representation of the given JSON data."""
245 245 if isinstance(json_data, basestring):
246 Note that this function is not safe against ambiguous tags 246 json_data = json.loads(json_data)
247 containing differently distributed children, e.g.:
248
249 '<a><b><c/></b><b><d/></b></a>'
250 vs.
251 '<a><b/><b><c/><d/></b></a>'
252
253 This is irrelevant for comparing the XML used by the tests of this
254 module.
255 """
256 def get_leafs_string(tree):
257 """Recursively build a string representing all xml leaf-nodes."""
258 root_str = '{}|{}|{}'.format(tree.tag, tree.tail, tree.text).strip()
259 result = []
260
261 if len(tree) > 0:
262 for subtree in tree:
263 for leaf in get_leafs_string(subtree):
264 result.append('{}__{}'.format(root_str, leaf))
265 for k, v in tree.attrib.items():
266 result.append('{}__{}:{}'.format(root_str, k, v))
267 else:
268 result.append(root_str)
269 return result
270
271 # XML data itself shall not be sorted, hence we can safely sort
272 # our string representations in order to produce a valid unified diff.
273 return sorted(get_leafs_string(ElementTree.fromstring(xml)))
274
275
276 def comparable_json(json_string):
277 """Create a nonambiguous representation of a given JSON string."""
278 return json.dumps( 247 return json.dumps(
279 json.loads(json_string), sort_keys=True, indent=0 248 json_data, sort_keys=True, indent=0
280 ).split('\n') 249 ).split('\n')
281 250
282 251
252 def comparable_xml(xml):
253 """Create a nonambiguous representation of a given XML tree."""
254 def strip(s):
255 if s is None:
256 return ''
257 return s.strip()
258
259 def transform(elt):
260 subs = sorted(transform(s) for s in elt)
261 return (elt.tag, strip(elt.tail), strip(elt.text), elt.attrib, subs)
262
263 return comparable_json(transform(ElementTree.fromstring(xml)))
264
265
283 def assert_manifest_content(manifest, expected_path): 266 def assert_manifest_content(manifest, expected_path):
284 extension = os.path.basename(expected_path).split('.')[-1] 267 extension = os.path.basename(expected_path).split('.')[-1]
285 268
286 with open(expected_path, 'r') as fp: 269 with open(expected_path, 'r') as fp:
287 if extension == 'xml': 270 if extension == 'xml':
288 generated = comparable_xml(manifest) 271 generated = comparable_xml(manifest)
289 expected = comparable_xml(fp.read()) 272 expected = comparable_xml(fp.read())
290 else: 273 else:
291 generated = comparable_json(manifest) 274 generated = comparable_json(manifest)
292 expected = comparable_json(fp.read()) 275 expected = comparable_json(fp.read())
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 expected = os.path.join( 459 expected = os.path.join(
477 os.path.dirname(__file__), 460 os.path.dirname(__file__),
478 'expecteddata', 461 'expecteddata',
479 filename.format(name, ext), 462 filename.format(name, ext),
480 ) 463 )
481 464
482 assert_manifest_content( 465 assert_manifest_content(
483 package.read(os.path.join(folder, '{}.{}'.format(name, ext))), 466 package.read(os.path.join(folder, '{}.{}'.format(name, ext))),
484 expected, 467 expected,
485 ) 468 )
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld