1#!/usr/bin/env python
2# Copyright 2013 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.
5
6"""Tests for the module module, which contains Module and related classes."""
7
8import os
9import unittest
10
11from tvcm import fake_fs
12from tvcm import module
13from tvcm import resource_loader
14from tvcm import project as project_module
15
16
17class ModuleIntegrationTests(unittest.TestCase):
18
19  def test_module(self):
20    fs = fake_fs.FakeFS()
21    fs.AddFile('/src/x.html', """
22<!DOCTYPE html>
23<link rel="import" href="/y.html">
24<link rel="import" href="/z.html">
25<script>
26'use strict';
27</script>
28""")
29    fs.AddFile('/src/y.html', """
30<!DOCTYPE html>
31<link rel="import" href="/z.html">
32""")
33    fs.AddFile('/src/z.html', """
34<!DOCTYPE html>
35""")
36    fs.AddFile('/src/tvcm.html', '<!DOCTYPE html>')
37    with fs:
38      project = project_module.Project([os.path.normpath('/src/')])
39      loader = resource_loader.ResourceLoader(project)
40      x_module = loader.LoadModule('x')
41
42      self.assertEquals([loader.loaded_modules['y'],
43                         loader.loaded_modules['z']],
44                        x_module.dependent_modules)
45
46      already_loaded_set = set()
47      load_sequence = []
48      x_module.ComputeLoadSequenceRecursive(load_sequence, already_loaded_set)
49
50      self.assertEquals([loader.loaded_modules['z'],
51                         loader.loaded_modules['y'],
52                         x_module],
53                        load_sequence)
54
55  def testBasic(self):
56    fs = fake_fs.FakeFS()
57    fs.AddFile('/x/src/my_module.html', """
58<!DOCTYPE html>
59<link rel="import" href="/tvcm/foo.html">
60});
61""")
62    fs.AddFile('/x/tvcm/foo.html', """
63<!DOCTYPE html>
64});
65""")
66    project = project_module.Project([os.path.normpath('/x')])
67    loader = resource_loader.ResourceLoader(project)
68    with fs:
69      my_module = loader.LoadModule(module_name='src.my_module')
70      dep_names = [x.name for x in my_module.dependent_modules]
71      self.assertEquals(['tvcm.foo'], dep_names)
72
73  def testDepsExceptionContext(self):
74    fs = fake_fs.FakeFS()
75    fs.AddFile('/x/src/my_module.html', """
76<!DOCTYPE html>
77<link rel="import" href="/tvcm/foo.html">
78""")
79    fs.AddFile('/x/tvcm/foo.html', """
80<!DOCTYPE html>
81<link rel="import" href="missing.html">
82""")
83    project = project_module.Project([os.path.normpath('/x')])
84    loader = resource_loader.ResourceLoader(project)
85    with fs:
86      exc = None
87      try:
88        loader.LoadModule(module_name='src.my_module')
89        assert False, 'Expected an exception'
90      except module.DepsException, e:
91        exc = e
92      self.assertEquals(
93          ['src.my_module', 'tvcm.foo'],
94          exc.context)
95
96  def testGetAllDependentFilenamesRecursive(self):
97    fs = fake_fs.FakeFS()
98    fs.AddFile('/x/y/z/foo.html', """
99<!DOCTYPE html>
100<link rel="import" href="/z/foo2.html">
101<link rel="stylesheet" href="/z/foo.css">
102<script src="/bar.js"></script>
103""")
104    fs.AddFile('/x/y/z/foo.css', """
105.x .y {
106    background-image: url(foo.jpeg);
107}
108""")
109    fs.AddFile('/x/y/z/foo.jpeg', '')
110    fs.AddFile('/x/y/z/foo2.html', """
111<!DOCTYPE html>
112""")
113    fs.AddFile('/x/raw/bar.js', 'hello')
114    project = project_module.Project([
115        os.path.normpath('/x/y'), os.path.normpath('/x/raw/')])
116    loader = resource_loader.ResourceLoader(project)
117    with fs:
118      my_module = loader.LoadModule(module_name='z.foo')
119      self.assertEquals(1, len(my_module.dependent_raw_scripts))
120
121      dependent_filenames = my_module.GetAllDependentFilenamesRecursive()
122      self.assertEquals(
123          [
124              os.path.normpath('/x/y/z/foo.html'),
125              os.path.normpath('/x/raw/bar.js'),
126              os.path.normpath('/x/y/z/foo.css'),
127              os.path.normpath('/x/y/z/foo.jpeg'),
128              os.path.normpath('/x/y/z/foo2.html'),
129          ],
130          dependent_filenames)
131