+ checker = TraceChecker(p.stdout, self.ref_dump, self.verbose)
+ checker.check()
+ p.wait()
+ if p.returncode != 0:
+ fail('`apitrace dump` returned code %i' % p.returncode)
+
+ self.doubleBuffer = checker.doubleBuffer
+
+ for callNo, refImageFileName in checker.images:
+ self.checkImage(callNo, refImageFileName)
+ for callNo, refStateFileName in checker.states:
+ self.checkState(callNo, refStateFileName)
+
+ def checkImage(self, callNo, refImageFileName):
+ srcImage = self.getImage(callNo)
+ refImage = Image.open(refImageFileName)
+
+ from snapdiff import Comparer
+ comparer = Comparer(refImage, srcImage)
+ match = comparer.ae()
+ if not match:
+ prefix = '%s.%u' % (self.getNamePrefix(), callNo)
+ srcImageFileName = prefix + '.src.png'
+ diffImageFileName = prefix + '.diff.png'
+ comparer.write_diff(diffImageFileName)
+ fail('snapshot from call %u does not match %s' % (callNo, refImageFileName))
+
+ def checkState(self, callNo, refStateFileName):
+ srcState = self.getState(callNo)
+ refState = self.getRefState(refStateFileName)
+
+ from jsondiff import Comparer, Differ
+ comparer = Comparer(ignore_added = True)
+ match = comparer.visit(refState, srcState)
+ if not match:
+ prefix = '%s.%u' % (self.getNamePrefix(), callNo)
+ srcStateFileName = prefix + '.src.json'
+ diffStateFileName = prefix + '.diff.json'
+ self.saveState(srcState, srcStateFileName)
+ #diffStateFile = open(diffStateFileName, 'wt')
+ diffStateFile = sys.stdout
+ differ = Differ(diffStateFile, ignore_added = True)
+ differ.visit(refState, srcState)
+ fail('state from call %u does not match %s' % (callNo, refStateFileName))
+
+ # Allo non-standard JS comments in JSON
+ json_comment_re = re.compile(r'//.*$', re.MULTILINE)
+
+ def getRefState(self, refStateFileName):
+ data = open(refStateFileName, 'rt').read()
+ data = self.json_comment_re.sub('', data)
+ state = json.loads(data, strict=False)
+ self.adjustRefState(state)
+ return state
+
+ def getNamePrefix(self):
+ name = os.path.basename(self.ref_dump)
+ try:
+ index = name.index('.')
+ except ValueError:
+ pass
+ else:
+ name = name[:index]
+ return name