Project

General

Profile

Download (2.64 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / test / haketilo_test / script_loader.py @ fd9f2fc4

1
# SPDX-License-Identifier: GPL-3.0-or-later
2

    
3
"""
4
Loading of parts of Haketilo source for testing in browser
5
"""
6

    
7
# This file is part of Haketilo.
8
#
9
# Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the GNU General Public License as published by
13
# the Free Software Foundation, either version 3 of the License, or
14
# (at your option) any later version.
15
#
16
# This program is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
# GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License
22
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
#
24
# I, Wojtek Kosior, thereby promise not to sue for violation of this file's
25
# license. Although I request that you do not make use of this code in a
26
# proprietary program, I am not going to enforce this in court.
27

    
28
from pathlib import Path
29
import subprocess, re
30

    
31
from .misc_constants import *
32

    
33
def make_relative_path(path):
34
    path = Path(path)
35

    
36
    if path.is_absolute():
37
        path = path.relative_to(proj_root)
38

    
39
    return path
40

    
41
script_cache = {}
42

    
43
def load_script(path, code_to_add=None):
44
    """
45
    `path` is a .js file path in Haketilo sources. It may be absolute or
46
    specified relative to Haketilo's project directory. `code_to_add` is
47
    optional code to be appended to the end of the main file being imported.
48
    it can contain directives like `#IMPORT`.
49

    
50
    Return a string containing script from `path` together with all other
51
    scripts it depends on. Dependencies are wrapped in the same way Haketilo's
52
    build system wraps them, with imports properly satisfied. The main script
53
    being loaded is wrapped partially - it also has its imports satisfied, but
54
    its code is executed in global scope instead of within an anonymous function
55
    and imported variables are defined with `let` instead of `const` to allow
56
    a dependency to be substituted by a mocked value.
57
    """
58
    path = make_relative_path(path)
59
    key = (str(path), code_to_add)
60
    if key in script_cache:
61
        return script_cache[key]
62

    
63
    append_flags = () if code_to_add is None else ('-A', ':'.join(key))
64

    
65
    awk = subprocess.run(['awk', '-f', awk_script_name, '--',
66
                          *unit_test_defines, *append_flags,
67
                          '--output=amalgamate-js:' + str(path)],
68
                         stdout=subprocess.PIPE, cwd=proj_root, check=True)
69
    script = awk.stdout.decode()
70
    script_cache[key] = script
71

    
72
    return script
(8-8/11)