18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# Copyright 2011 the V8 project authors. All rights reserved.
28b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# Redistribution and use in source and binary forms, with or without
38b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# modification, are permitted provided that the following conditions are
48b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# met:
58b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#
68b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#     * Redistributions of source code must retain the above copyright
78b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       notice, this list of conditions and the following disclaimer.
88b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#     * Redistributions in binary form must reproduce the above
98b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       copyright notice, this list of conditions and the following
108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       disclaimer in the documentation and/or other materials provided
118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       with the distribution.
128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#     * Neither the name of Google Inc. nor the names of its
138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       contributors may be used to endorse or promote products derived
148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#       from this software without specific prior written permission.
158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#
168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochimport test
298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochimport os
3069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfrom os.path import join, dirname, exists, isfile
318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochimport platform
328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochimport utils
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochimport re
348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass PreparserTestCase(test.TestCase):
368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def __init__(self, root, path, executable, mode, throws, context, source):
388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    super(PreparserTestCase, self).__init__(context, path, mode)
398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    self.executable = executable
408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    self.root = root
41257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    self.throws = throws
42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    self.source = source
438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def GetLabel(self):
458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return "%s %s %s" % (self.mode, self.path[-2], self.path[-1])
468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def GetName(self):
488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return self.path[-1]
498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def HasSource(self):
51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return self.source is not None
52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def GetSource():
54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return self.source
55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def BuildCommand(self, path):
57257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (self.source is not None):
58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = [self.executable, "-e", self.source]
59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    else:
60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      testfile = join(self.root, self.GetName()) + ".js"
61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = [self.executable, testfile]
62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (self.throws):
63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result += ['throws'] + self.throws
648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return result
658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def GetCommand(self):
678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return self.BuildCommand(self.path)
688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def Run(self):
708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return test.TestCase.Run(self)
718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass PreparserTestConfiguration(test.TestConfiguration):
748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def __init__(self, context, root):
768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    super(PreparserTestConfiguration, self).__init__(context, root)
778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def GetBuildRequirements(self):
798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return ['preparser']
808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def GetExpectations(self):
82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    expects_file = join(self.root, 'preparser.expectation')
83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    map = {}
84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if exists(expects_file):
85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$")
86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      for line in utils.ReadLinesFrom(expects_file):
87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (line[0] == '#'): continue
88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        rule_match = rule_regex.match(line)
89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if rule_match:
90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          expects = []
91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          if (rule_match.group(2)):
92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            expects = expects + [rule_match.group(2)]
93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            if (rule_match.group(3)):
94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              expects = expects + [rule_match.group(3), rule_match.group(4)]
95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          map[rule_match.group(1)] = expects
96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return map;
97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def ParsePythonTestTemplates(self, result, filename,
99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               executable, current_path, mode):
100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    pathname = join(self.root, filename + ".pyt")
101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    def Test(name, source, expectation):
102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      throws = None
103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (expectation is not None):
104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        throws = [expectation]
105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      test = PreparserTestCase(self.root,
106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               current_path + [filename, name],
107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               executable,
108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               mode, throws, self.context,
109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               source.replace("\n", " "))
110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result.append(test)
111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    def Template(name, source):
112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      def MkTest(replacement, expectation):
113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        testname = name
114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        testsource = source
115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        for key in replacement.keys():
116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          testname = testname.replace("$"+key, replacement[key]);
117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          testsource = testsource.replace("$"+key, replacement[key]);
118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Test(testname, testsource, expectation)
119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return MkTest
120589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    execfile(pathname, {"Test": Test, "Template": Template})
121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def ListTests(self, current_path, path, mode, variant_flags):
12369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    executable = 'preparser'
1248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    if utils.IsWindows():
1258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      executable += '.exe'
1268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    executable = join(self.context.buildspace, executable)
12769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if not isfile(executable):
12869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      executable = join('obj', 'preparser', mode, 'preparser')
12969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      if utils.IsWindows():
13069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        executable += '.exe'
13169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      executable = join(self.context.buildspace, executable)
132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    expectations = self.GetExpectations()
133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    result = []
1348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    # Find all .js files in tests/preparser directory.
1358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    filenames = [f[:-3] for f in os.listdir(self.root) if f.endswith(".js")]
1368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    filenames.sort()
1378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    for file in filenames:
138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      throws = None;
139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (file in expectations):
140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        throws = expectations[file]
1418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      result.append(PreparserTestCase(self.root,
1428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                      current_path + [file], executable,
143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                      mode, throws, self.context, None))
144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    # Find all .pyt files in test/preparser directory.
145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    filenames = [f[:-4] for f in os.listdir(self.root) if f.endswith(".pyt")]
146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    filenames.sort()
147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    for file in filenames:
148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      # Each file as a python source file to be executed in a specially
149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      # created environment (defining the Template and Test functions)
150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      self.ParsePythonTestTemplates(result, file,
151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    executable, current_path, mode)
1528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return result
1538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  def GetTestStatus(self, sections, defs):
1558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    status_file = join(self.root, 'preparser.status')
1568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    if exists(status_file):
1578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      test.ReadConfigurationInto(status_file, sections, defs)
1588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  def VariantFlags(self):
160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return [[]];
161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochdef GetConfiguration(context, root):
1648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return PreparserTestConfiguration(context, root)
165