mirror of https://github.com/tc39/test262.git
provide fallback parser if YAML not installed
parseTestRecord.py: - recover from ImportError when YAML not defined - use monkeyYaml as backup monkeyYaml.py: - parser for subset of YAML used in test262 frontmatter test_monkeyYaml.py: - unit tests
This commit is contained in:
parent
9bd668692e
commit
4f9cec2fa8
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2014 by Sam Mikes. All rights reserved.
|
||||
# This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
# This code provides a fallback parser that can handle the subset of
|
||||
# YAML used in test262 frontmatter
|
||||
|
||||
import re
|
||||
|
||||
mYamlKV = re.compile(r"(.*?):(.*)")
|
||||
mYamlIntDigits = re.compile(r"^[-0-9]*$")
|
||||
mYamlFloatDigits = re.compile(r"^[-.0-9eE]*$")
|
||||
mYamlListPattern = re.compile(r"^\[(.*)\]$")
|
||||
mYamlMultilineList = re.compile(r"^ *- (.*)$")
|
||||
|
||||
def load(str):
|
||||
dict = None
|
||||
|
||||
lines = str.split("\n")
|
||||
while lines:
|
||||
line = lines.pop(0)
|
||||
if myIsAllSpaces(line):
|
||||
continue
|
||||
result = mYamlKV.match(line)
|
||||
if result:
|
||||
if not dict:
|
||||
dict = {}
|
||||
key = result.group(1).strip()
|
||||
value = result.group(2).strip()
|
||||
(lines, value) = myReadValue(lines, value)
|
||||
dict[key] = value
|
||||
else:
|
||||
raise Exception("monkeyYaml is confused at " + line)
|
||||
return dict
|
||||
|
||||
def myReadValue(lines, value):
|
||||
if value == ">":
|
||||
(lines, value) = myMultiline(lines, value)
|
||||
value = value + "\n"
|
||||
return (lines, value)
|
||||
if lines and not value and myMaybeList(lines[0]):
|
||||
return myMultilineList(lines, value)
|
||||
else:
|
||||
return lines, myReadOneLine(value)
|
||||
|
||||
def myMaybeList(value):
|
||||
return mYamlMultilineList.match(value)
|
||||
|
||||
def myMultilineList(lines, value):
|
||||
# assume no explcit indentor (otherwise have to parse value)
|
||||
value = []
|
||||
indent = None
|
||||
while lines:
|
||||
line = lines.pop(0)
|
||||
leading = myLeadingSpaces(line)
|
||||
if myIsAllSpaces(line):
|
||||
pass
|
||||
elif leading < indent:
|
||||
lines.insert(0, line)
|
||||
break;
|
||||
else:
|
||||
indent = indent or leading
|
||||
value += [myReadOneLine(myRemoveListHeader(indent, line))]
|
||||
return (lines, value)
|
||||
|
||||
def myRemoveListHeader(indent, line):
|
||||
line = line[indent:]
|
||||
return mYamlMultilineList.match(line).group(1)
|
||||
|
||||
def myReadOneLine(value):
|
||||
if mYamlListPattern.match(value):
|
||||
return myFlowList(value)
|
||||
elif mYamlIntDigits.match(value):
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
elif mYamlFloatDigits.match(value):
|
||||
try:
|
||||
value = float(value)
|
||||
except ValueError:
|
||||
pass
|
||||
return value
|
||||
|
||||
def myFlowList(value):
|
||||
result = mYamlListPattern.match(value)
|
||||
values = result.group(1).split(",")
|
||||
return [myReadOneLine(v.strip()) for v in values]
|
||||
|
||||
def myMultiline(lines, value):
|
||||
# assume no explcit indentor (otherwise have to parse value)
|
||||
value = []
|
||||
indent = 1
|
||||
while lines:
|
||||
line = lines.pop(0)
|
||||
if myIsAllSpaces(line):
|
||||
value += ["\n"]
|
||||
elif myLeadingSpaces(line) < indent:
|
||||
lines.insert(0, line)
|
||||
break;
|
||||
else:
|
||||
value += [line[(indent):]]
|
||||
value = " ".join(value)
|
||||
return (lines, value)
|
||||
|
||||
def myIsAllSpaces(line):
|
||||
return len(line.strip()) == 0
|
||||
|
||||
def myLeadingSpaces(line):
|
||||
return len(line) - len(line.lstrip(' '))
|
|
@ -17,8 +17,6 @@ import sys
|
|||
import tempfile
|
||||
import time
|
||||
|
||||
import yaml
|
||||
|
||||
# from TestCasePackagerConfig import *
|
||||
|
||||
headerPatternStr = r"(?:(?:\s*\/\/.*)?\s*\n)*"
|
||||
|
@ -39,6 +37,8 @@ atattrs = re.compile(r"\s*\n\s*\*\s*@")
|
|||
yamlPattern = re.compile(r"---((?:\s|\S)*)---")
|
||||
newlinePattern = re.compile(r"\n")
|
||||
|
||||
yamlLoad = None
|
||||
|
||||
def stripStars(text):
|
||||
return stars.sub('\n', text).strip()
|
||||
|
||||
|
@ -76,7 +76,8 @@ def oldAttrParser(testRecord, body, name):
|
|||
def yamlAttrParser(testRecord, attrs, name):
|
||||
match = yamlPattern.match(attrs)
|
||||
body = match.group(1)
|
||||
parsed = yaml.load(body)
|
||||
importYamlLoad()
|
||||
parsed = yamlLoad(body)
|
||||
|
||||
if (parsed is None):
|
||||
print "Failed to parse yaml in name %s"%(name)
|
||||
|
@ -106,3 +107,14 @@ def parseTestRecord(src, name):
|
|||
oldAttrParser(testRecord, attrs, name)
|
||||
|
||||
return testRecord
|
||||
|
||||
def importYamlLoad():
|
||||
global yamlLoad
|
||||
if yamlLoad:
|
||||
return
|
||||
try:
|
||||
import yaml
|
||||
yamlLoad = yaml.load
|
||||
except ImportError:
|
||||
import monkeyYaml
|
||||
yamlLoad = monkeyYaml.load
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2014 by Sam Mikes. All rights reserved.
|
||||
# This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
import unittest
|
||||
|
||||
import os
|
||||
import yaml
|
||||
|
||||
# add parent dir to search path
|
||||
import sys
|
||||
sys.path.insert(0, "..")
|
||||
|
||||
import monkeyYaml
|
||||
|
||||
class TestMonkeyYAMLParsing(unittest.TestCase):
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(monkeyYaml.load(""), yaml.load(""))
|
||||
|
||||
def test_newline(self):
|
||||
self.assertEqual(monkeyYaml.load("\n"), yaml.load("\n"))
|
||||
|
||||
def test_oneline(self):
|
||||
y = "foo: bar"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_twolines(self):
|
||||
y = "foo: bar\nbaz_bletch : blith:er"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_multiLine(self):
|
||||
y = "foo: >\n bar\nbaz: 3"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_es5id(self):
|
||||
y = "es5id: 15.2.3.6-4-102"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_Multiline_1(self):
|
||||
lines = [" foo"]
|
||||
value = ">"
|
||||
y = "\n".join([value] + lines)
|
||||
(lines, value) = monkeyYaml.myMultiline(lines, value)
|
||||
self.assertEqual(lines, [])
|
||||
self.assertEqual(value, yaml.load(y))
|
||||
|
||||
def test_Multiline_1(self):
|
||||
lines = [" foo", " bar"]
|
||||
value = ">"
|
||||
y = "\n".join([value] + lines)
|
||||
(lines, value) = monkeyYaml.myMultiline(lines, value)
|
||||
self.assertEqual(lines, [])
|
||||
self.assertEqual(value, yaml.load(y))
|
||||
|
||||
def test_myLeading(self):
|
||||
self.assertEqual(2, monkeyYaml.myLeadingSpaces(" foo"))
|
||||
self.assertEqual(2, monkeyYaml.myLeadingSpaces(" "))
|
||||
self.assertEqual(0, monkeyYaml.myLeadingSpaces("\t "))
|
||||
|
||||
def test_includes_flow(self):
|
||||
y = "includes: [a.js,b.js, c_with_wings.js]\n"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_myFlowList_1(self):
|
||||
y = "[a.js,b.js, c_with_wings.js, 3, 4.12]"
|
||||
self.assertEqual(monkeyYaml.myFlowList(y), ['a.js', 'b.js', 'c_with_wings.js', 3, 4.12])
|
||||
|
||||
def test_multiline_list_1(self):
|
||||
y = "foo:\n - bar\n - baz"
|
||||
self.assertEqual(monkeyYaml.load(y), yaml.load(y))
|
||||
|
||||
def test_mulineline_list2(self):
|
||||
self.assertEqual(monkeyYaml.myRemoveListHeader(2, " - foo"), "foo")
|
||||
|
||||
def test_mulineline_list3(self):
|
||||
(lines, value) = monkeyYaml.myMultilineList([" - foo", " - bar", "baz: bletch"], "")
|
||||
self.assertEqual(lines, ["baz: bletch"])
|
||||
self.assertEqual(value, ["foo", "bar"])
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue