Add support for [NoInterfaceObject] Web IDL extended attribute
[WebKit-https.git] / Tools / Scripts / webkitpy / bindings / main.py
1 # Copyright (C) 2011 Google Inc.  All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1. Redistributions of source code must retain the above copyright
7 #    notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 #    notice, this list of conditions and the following disclaimer in the
10 #    documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 #
24
25 import os
26 import os.path
27 import shutil
28 import subprocess
29 import sys
30 import tempfile
31 from webkitpy.common.checkout.scm.detection import detect_scm_system
32 from webkitpy.common.system.executive import ScriptError
33
34
35 class BindingsTests:
36
37     def __init__(self, reset_results, generators, executive):
38         self.reset_results = reset_results
39         self.generators = generators
40         self.executive = executive
41
42     def generate_from_idl(self, generator, idl_file, output_directory, supplemental_dependency_file):
43         cmd = ['perl', '-w',
44                '-IWebCore/bindings/scripts',
45                'WebCore/bindings/scripts/generate-bindings.pl',
46                # idl include directories (path relative to generate-bindings.pl)
47                '--include', '.',
48                '--defines', 'TESTING_%s' % generator,
49                '--generator', generator,
50                '--outputDir', output_directory,
51                '--supplementalDependencyFile', supplemental_dependency_file,
52                idl_file]
53
54         exit_code = 0
55         try:
56             output = self.executive.run_command(cmd)
57             if output:
58                 print output
59         except ScriptError, e:
60             print e.output
61             exit_code = e.exit_code
62         return exit_code
63
64     def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file, window_constructors_file):
65         idl_files_list = tempfile.mkstemp()
66         for input_file in os.listdir(input_directory):
67             (name, extension) = os.path.splitext(input_file)
68             if extension != '.idl':
69                 continue
70             os.write(idl_files_list[0], os.path.join(input_directory, input_file) + "\n")
71         os.close(idl_files_list[0])
72
73         cmd = ['perl', '-w',
74                '-IWebCore/bindings/scripts',
75                'WebCore/bindings/scripts/preprocess-idls.pl',
76                '--idlFilesList', idl_files_list[1],
77                '--defines', '',
78                '--supplementalDependencyFile', supplemental_dependency_file,
79                '--windowConstructorsFile', window_constructors_file]
80
81         exit_code = 0
82         try:
83             output = self.executive.run_command(cmd)
84             if output:
85                 print output
86         except ScriptError, e:
87             print e.output
88             exit_code = e.exit_code
89         os.remove(idl_files_list[1])
90         return exit_code
91
92     def detect_changes(self, generator, work_directory, reference_directory):
93         changes_found = False
94         for output_file in os.listdir(work_directory):
95             cmd = ['diff',
96                    '-u',
97                    '-N',
98                    os.path.join(reference_directory, output_file),
99                    os.path.join(work_directory, output_file)]
100
101             exit_code = 0
102             try:
103                 output = self.executive.run_command(cmd)
104             except ScriptError, e:
105                 output = e.output
106                 exit_code = e.exit_code
107
108             if exit_code or output:
109                 print 'FAIL: (%s) %s' % (generator, output_file)
110                 print output
111                 changes_found = True
112             else:
113                 print 'PASS: (%s) %s' % (generator, output_file)
114         return changes_found
115
116     def run_tests(self, generator, input_directory, reference_directory, supplemental_dependency_file):
117         work_directory = reference_directory
118
119         passed = True
120         for input_file in os.listdir(input_directory):
121             (name, extension) = os.path.splitext(input_file)
122             if extension != '.idl':
123                 continue
124             # Generate output into the work directory (either the given one or a
125             # temp one if not reset_results is performed)
126             if not self.reset_results:
127                 work_directory = tempfile.mkdtemp()
128
129             if self.generate_from_idl(generator,
130                                       os.path.join(input_directory, input_file),
131                                       work_directory,
132                                       supplemental_dependency_file):
133                 passed = False
134
135             if self.reset_results:
136                 print "Reset results: (%s) %s" % (generator, input_file)
137                 continue
138
139             # Detect changes
140             if self.detect_changes(generator, work_directory, reference_directory):
141                 passed = False
142             shutil.rmtree(work_directory)
143
144         return passed
145
146     def main(self):
147         current_scm = detect_scm_system(os.curdir)
148         os.chdir(os.path.join(current_scm.checkout_root, 'Source'))
149
150         all_tests_passed = True
151
152         input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
153         supplemental_dependency_file = tempfile.mkstemp()[1]
154         window_constructors_file = tempfile.mkstemp()[1]
155         if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file, window_constructors_file):
156             print 'Failed to generate a supplemental dependency file.'
157             os.remove(supplemental_dependency_file)
158             return -1
159
160         for generator in self.generators:
161             input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
162             reference_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test', generator)
163             if not self.run_tests(generator, input_directory, reference_directory, supplemental_dependency_file):
164                 all_tests_passed = False
165
166         os.remove(supplemental_dependency_file)
167         print ''
168         if all_tests_passed:
169             print 'All tests PASS!'
170             return 0
171         else:
172             print 'Some tests FAIL! (To update the reference files, execute "run-bindings-tests --reset-results")'
173             return -1