Merge pull request #4 from caitp/anbafy-it
Incorporate changes from test262/41edfcebce1a85096
diff --git a/src/parseTestRecord.py b/src/parseTestRecord.py
index 22d5664..6982540 100644
--- a/src/parseTestRecord.py
+++ b/src/parseTestRecord.py
@@ -6,79 +6,41 @@
# TODO: resolve differences with common.py and unify into one file.
-import logging
-import optparse
+from __future__ import print_function
+
import os
-from os import path
-import platform
import re
-import subprocess
-import sys
-import tempfile
-import time
import imp
from _monkeyYaml import load as yamlLoad
-headerPatternStr = r"(?:(?:\s*\/\/.*)?\s*\n)*"
-captureCommentPatternStr = r"\/\*\*?((?:\s|\S)*?)\*\/\s*\n"
-anyPatternStr = r"(?:\s|\S)*"
+#def onerror(message):
+# print(message)
-headerPattern = re.compile("^" + headerPatternStr)
+# Matches trailing whitespace and any following blank lines.
+_BLANK_LINES = r"([ \t]*[\r\n]{1,2})*"
-# Should match anything
-testRecordPattern = re.compile(r"^(" + headerPatternStr +
- r")(?:" + captureCommentPatternStr +
- r")?(" + anyPatternStr +
- r")$")
+# Matches the YAML frontmatter block.
+_YAML_PATTERN = re.compile(r"/\*---(.*)---\*/" + _BLANK_LINES, re.DOTALL)
-stars = re.compile(r"\s*\n\s*\*\s?")
-atattrs = re.compile(r"\s*\n\s*\*\s*@")
+# Matches all known variants for the license block.
+_LICENSE_PATTERN = re.compile(
+ r'// Copyright( \(C\))? (\w+) .+\. {1,2}All rights reserved\.[\r\n]{1,2}' +
+ r'(' +
+ r'// This code is governed by the( BSD)? license found in the LICENSE file\.' +
+ r'|' +
+ r'// See LICENSE for details\.' +
+ r'|' +
+ r'// Use of this source code is governed by a BSD-style license that can be[\r\n]{1,2}' +
+ r'// found in the LICENSE file\.' +
+ r'|' +
+ r'// See LICENSE or https://github\.com/tc39/test262/blob/master/LICENSE' +
+ r')[\r\n]{1,2}' + _BLANK_LINES, re.IGNORECASE)
-yamlPattern = re.compile(r"---((?:\s|\S)*)---")
-newlinePattern = re.compile(r"\n")
-
-def stripStars(text):
- return stars.sub('\n', text).strip()
-
-def stripHeader(src):
- header = headerPattern.match(src).group(0)
- return src[len(header):]
-
-def matchParts(src, name):
- match = testRecordPattern.match(src)
- if match == None:
- raise Exception('unrecognized: ' + name)
- return match
-
-def hasYAML(text):
- match = yamlPattern.match(text)
- if match == None:
- return False
- return True
-
-def oldAttrParser(testRecord, body, name):
- propTexts = atattrs.split(body)
- testRecord['commentary'] = stripStars(propTexts[0])
- del propTexts[0]
- for propText in propTexts:
- propMatch = re.match(r"^\w+", propText)
- if propMatch == None:
- raise Exception('Malformed "@" attribute: ' + name)
- propName = propMatch.group(0)
- propVal = stripStars(propText[len(propName):])
-
- if propName in testRecord:
- raise Exception('duplicate: ' + propName)
- testRecord[propName] = propVal;
-
-def yamlAttrParser(testRecord, attrs, name):
- match = yamlPattern.match(attrs)
- body = match.group(1)
- parsed = yamlLoad(body)
-
- if (parsed is None):
- print "Failed to parse yaml in name %s"%(name)
+def yamlAttrParser(testRecord, attrs, name, onerror = print):
+ parsed = yamlLoad(attrs)
+ if parsed is None:
+ onerror("Failed to parse yaml in name %s" % name)
return
for key in parsed:
@@ -91,17 +53,60 @@
for flag in testRecord['flags']:
testRecord[flag] = ""
-def parseTestRecord(src, name):
- testRecord = {}
- match = matchParts(src, name)
- testRecord['header'] = match.group(1).strip()
- testRecord['test'] = match.group(3) # do not trim
+def findLicense(src):
+ match = _LICENSE_PATTERN.search(src)
+ if not match:
+ return None
- attrs = match.group(2)
+ return match.group(0)
+
+def findAttrs(src):
+ match = _YAML_PATTERN.search(src)
+ if not match:
+ return (None, None)
+
+ return (match.group(0), match.group(1).strip())
+
+def parseTestRecord(src, name, onerror = print):
+ # Find the license block.
+ header = findLicense(src)
+
+ # Find the YAML frontmatter.
+ (frontmatter, attrs) = findAttrs(src)
+
+ # YAML frontmatter is required for all tests.
+ if frontmatter is None:
+ onerror("Missing frontmatter: %s" % name)
+
+ # The license shuold be placed before the frontmatter and there shouldn't be
+ # any extra content between the license and the frontmatter.
+ if header is not None and frontmatter is not None:
+ headerIdx = src.index(header)
+ frontmatterIdx = src.index(frontmatter)
+ if headerIdx > frontmatterIdx:
+ onerror("Unexpected license after frontmatter: %s" % name)
+
+ # Search for any extra test content, but ignore whitespace only or comment lines.
+ extra = src[headerIdx + len(header) : frontmatterIdx]
+ if extra and any(line.strip() and not line.lstrip().startswith("//") for line in extra.split("\n")):
+ onerror("Unexpected test content between license and frontmatter: %s" % name)
+
+ # Remove the license and YAML parts from the actual test content.
+ test = src
+ if frontmatter is not None:
+ test = test.replace(frontmatter, '')
+ if header is not None:
+ test = test.replace(header, '')
+
+ testRecord = {}
+ testRecord['header'] = header.strip() if header else ''
+ testRecord['test'] = test
+
if attrs:
- if hasYAML(attrs):
- yamlAttrParser(testRecord, attrs, name)
- else:
- oldAttrParser(testRecord, attrs, name)
+ yamlAttrParser(testRecord, attrs, name, onerror)
+
+ # Report if the license block is missing in non-generated tests.
+ if header is None and "generated" not in testRecord and "hashbang" not in name:
+ onerror("No license found in: %s" % name)
return testRecord