1#!/usr/bin/env python 2# Copyright (c) 2012 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5import unittest 6 7import parse_deps 8import os 9 10srcdir = os.path.join(os.path.dirname(__file__), "../src") 11 12class JSStripTests(unittest.TestCase): 13 def test_tokenize_0(self): 14 tokens = list(parse_deps._tokenize_js("")) 15 self.assertEquals([], tokens) 16 17 def test_tokenize_nl(self): 18 tokens = list(parse_deps._tokenize_js("\n")) 19 self.assertEquals(["\n"], tokens) 20 21 def test_tokenize_slashslash_comment(self): 22 tokens = list(parse_deps._tokenize_js("A // foo")) 23 self.assertEquals(["A ", "//", " foo"], tokens) 24 25 def test_tokenize_slashslash_comment_then_newline2(self): 26 tokens = list(parse_deps._tokenize_js("""A // foo 27bar""" 28)) 29 self.assertEquals(["A ", "//", " foo", "\n", "bar"], tokens) 30 31 def test_tokenize_cstyle_comment(self): 32 tokens = list(parse_deps._tokenize_js("""A /* foo */""")) 33 self.assertEquals(["A ", "/*", " foo ", "*/"], tokens) 34 35 def test_tokenize_cstyle_comment(self): 36 tokens = list(parse_deps._tokenize_js("""A /* foo 37*bar 38*/""")) 39 self.assertEquals(["A ", "/*", " foo", "\n", "*bar", "\n", "*/"], tokens) 40 41 def test_strip_comments(self): 42 self.assertEquals("A ", parse_deps._strip_js_comments("A // foo")) 43 44 self.assertEquals("A b", parse_deps._strip_js_comments("A /* foo */ b")) 45 self.assertEquals("A b", parse_deps._strip_js_comments("""A /* foo 46 */ b""")) 47 48 49class ParseTests(unittest.TestCase): 50 def test_parse_definition_1(self): 51 text = """// blahblahblah 52base.require('dependency1'); 53base.require('dependency2'); 54base.requireStylesheet('myStylesheet'); 55""" 56 module = parse_deps.Module("myModule") 57 module.parse_definition_(text) 58 self.assertEquals(["myStylesheet"], module.style_sheet_names); 59 self.assertEquals(["dependency1", "dependency2"], 60 module.dependent_module_names); 61 62 def test_parse_definition_missing_semis(self): 63 text = """// blahblahblah 64base.require('dependency1') 65base.require('dependency2'); 66base.requireStylesheet('myStylesheet') 67""" 68 module = parse_deps.Module("myModule") 69 module.parse_definition_(text) 70 self.assertEquals(["myStylesheet"], module.style_sheet_names); 71 self.assertEquals(["dependency1", "dependency2"], 72 module.dependent_module_names); 73 74 def test_parse_definition_with_deps_and_stylesheet_swapped(self): 75 text = """// blahblahblah 76base.require('dependency1'); 77base.requireStylesheet('myStylesheet'); 78base.require('dependency2'); 79""" 80 module = parse_deps.Module("myModule") 81 module.parse_definition_(text) 82 self.assertEquals(["myStylesheet"], module.style_sheet_names); 83 self.assertEquals(["dependency1", "dependency2"], 84 module.dependent_module_names); 85 86 def test_parse_empty_definition(self): 87 text = """// blahblahblah 88""" 89 module = parse_deps.Module("myModule") 90 module.parse_definition_(text, decl_required = False) 91 self.assertEquals([], module.style_sheet_names); 92 self.assertEquals([], module.dependent_module_names); 93 94 def test_parse_definition_3(self): 95 text = """// blahblahblah 96base.require('dependency1'); 97//base.require('dependency2'); 98""" 99 module = parse_deps.Module("myModule") 100 module.parse_definition_(text) 101 self.assertEquals([], module.style_sheet_names); 102 self.assertEquals(["dependency1"], module.dependent_module_names); 103 104 def test_parse_definition_4(self): 105 text = """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 106// Use of this source code is governed by a BSD-style license that can be 107// found in the LICENSE file. 108 109'use strict'; 110 111/** 112 * @fileoverview TimelineView visualizes TRACE_EVENT events using the 113 * tracing.TimelineTrackView component and adds in selection summary and 114 * control buttons. 115 */ 116base.requireStylesheet('timeline_view') 117base.require('timeline_track_view'); 118base.require('timeline_analysis'); 119base.require('overlay'); 120base.require('trace_event_importer'); 121base.require('linux_perf_importer'); 122base.exportsTo('tracing', function() {""" 123 124 module = parse_deps.Module("timeline_view") 125 module.parse_definition_(text) 126 self.assertEquals(["timeline_view"], module.style_sheet_names); 127 self.assertEquals(["timeline_track_view", 128 "timeline_analysis", 129 "overlay", 130 "trace_event_importer", 131 "linux_perf_importer"], module.dependent_module_names); 132 133 def test_parse_definition_with_definition_in_comments(self): 134 text = """// SomeComment 135/* 136 * All subclasses should depend on linux_perf_parser, e.g. 137 * 138 * base.require('linux_perf_parser'); 139 * base.exportTo('tracing', function() { }); 140 * 141 */ 142base.require('dependency1'); 143base.require('dependency2'); 144""" 145 module = parse_deps.Module("myModule") 146 module.parse_definition_(text) 147 self.assertEquals([], module.style_sheet_names); 148 self.assertEquals(["dependency1", "dependency2"], 149 module.dependent_module_names); 150 151 def test_parse_dependency_with_slashes(self): 152 text = """base.require("foo/dependency1") 153""" 154 module = parse_deps.Module("myModule") 155 self.assertRaises(parse_deps.DepsException, 156 lambda: module.parse_definition_(text)) 157 158 def test_parse_dependency_with_dots(self): 159 text = """base.require("foo.dependency1") 160""" 161 module = parse_deps.Module("myModule") 162 module.parse_definition_(text) 163 self.assertEquals([], module.style_sheet_names); 164 self.assertEquals(["foo.dependency1"], 165 module.dependent_module_names); 166 167 168class ResourceFinderStub(object): 169 def __init__(self): 170 self.modules = {} 171 172 def add_module(self, name, filename, contents): 173 module = {"filename": filename, 174 "contents": contents} 175 self.modules[name] = module 176 177 def find_and_load_module(self, current_module, requested_module_name): 178 if requested_module_name not in self.modules: 179 return None 180 return (self.modules[requested_module_name]["filename"], 181 self.modules[requested_module_name]["contents"]) 182 183 184x_contents = """ 185base.require('y'); 186base.require('z'); 187base.exportTo("xyz", function() { }); 188""" 189 190y_contents = """ 191base.require('z'); 192base.exportsTo("xyz", function() { }); 193""" 194 195z_contents = """ 196base.exportsTo("xyz", function() { }); 197""" 198 199class FlattenTests(unittest.TestCase): 200 def test_module(self): 201 resource_finder = ResourceFinderStub() 202 resource_finder.add_module("y", "y.js", y_contents); 203 resource_finder.add_module("z", "z.js", z_contents); 204 205 x_module = parse_deps.Module("x") 206 x_module.load_and_parse("x.js", x_contents) 207 208 all_resources = {} 209 x_module.resolve(all_resources, resource_finder) 210 211 self.assertEquals([all_resources["scripts"]["y"], 212 all_resources["scripts"]["z"]], 213 x_module.dependent_modules) 214 215 already_loaded_set = set() 216 load_sequence = [] 217 x_module.compute_load_sequence_recursive(load_sequence, already_loaded_set) 218 219 self.assertEquals([all_resources["scripts"]["z"], 220 all_resources["scripts"]["y"], 221 x_module], 222 load_sequence) 223 224 225class ResourceFinderTest(unittest.TestCase): 226 def test_basic(self): 227 228 resource_finder = parse_deps.ResourceFinder(srcdir) 229 module = parse_deps.Module("unittest") 230 module.load_and_parse(os.path.join(srcdir, "unittest.js")) 231 filename, contents = resource_finder.find_and_load_module(module, "base") 232 233 self.assertTrue(os.path.samefile(filename, os.path.join(srcdir, "base.js"))) 234 expected_contents = '' 235 with open(os.path.join(srcdir, "base.js")) as f: 236 expected_contents = f.read() 237 self.assertEquals(contents, expected_contents) 238 239 def test_dependency_in_subdir(self): 240 resource_finder = parse_deps.ResourceFinder(srcdir) 241 module = parse_deps.Module("unittest") 242 module.load_and_parse(os.path.join(srcdir, "unittest.js")) 243 filename, contents = resource_finder.find_and_load_module( 244 module, "tracks.track") 245 246 self.assertTrue(os.path.samefile(filename, os.path.join(srcdir, "tracks/track.js"))) 247 expected_contents = '' 248 with open(os.path.join(srcdir, "tracks/track.js")) as f: 249 expected_contents = f.read() 250 self.assertEquals(contents, expected_contents) 251 252 253class CalcLoadSequenceTest(unittest.TestCase): 254 def test_one_toplevel_nodeps(self): 255 load_sequence = parse_deps.calc_load_sequence( 256 [os.path.join(srcdir, "unittest.js")], srcdir) 257 name_sequence = [x.name for x in load_sequence] 258 self.assertEquals(["unittest"], name_sequence) 259 260 # Tests that we resolve deps between toplevels. 261 def test_calc_load_sequence_two_toplevels(self): 262 pass 263 264if __name__ == "__main__": 265 unittest.main() 266