1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
The `require()` function loads the specified module, executes it and returns
the returned value to the caller.
The global array `REQUIRE_SEARCH_PATH` specifies the list of locations to
check for a matching module file.
The return value of a successfully loaded module is cached in a global
registry, subsequent require calls with the same name will return the
cached value.
Throws an exception if the global `REQUIRE_SEARCH_PATH` variable is unset or
not pointing to an array.
Throws an exception if the requested module name cannot be found.
Throws an exception if a module file could be found but not opened.
Throws an exception if a module file could not be compiled.
Returns the value returned by the invoked module code (typically an object).
-- Testcase --
{%
push(REQUIRE_SEARCH_PATH, TESTFILES_PATH + '/*.uc');
let mod1 = require("require.test.module");
printf("require() #1 returned %.J\n\n", mod1);
let mod2 = require("require.test.module");
printf("require() #2 returned %.J\n\n", mod2);
printf("Instances are identical: %s\n\n", mod1 === mod2);
// deleting the entry from the global module registry forces reload
delete global.modules["require.test.module"];
let mod3 = require("require.test.module");
printf("require() #3 returned %.J\n\n", mod3);
printf("Instances are identical: %s\n\n", mod1 === mod3);
%}
-- End --
-- File require/test/module.uc --
print("This is require.test.module running!\n\n");
return {
greeting: function(name) {
printf("Hello, %s!\n", name);
}
};
-- End --
-- Expect stdout --
This is require.test.module running!
require() #1 returned {
"greeting": "function(name) { ... }"
}
require() #2 returned {
"greeting": "function(name) { ... }"
}
Instances are identical: true
This is require.test.module running!
require() #3 returned {
"greeting": "function(name) { ... }"
}
Instances are identical: false
-- End --
A clobbered `REQUIRE_SEARCH_PATH` triggers an exception.
-- Testcase --
{%
REQUIRE_SEARCH_PATH = null;
require("test");
%}
-- End --
-- Expect stderr --
Runtime error: Global require search path not set
In line 4, byte 16:
` require("test");`
Near here --------^
-- End --
A not found module triggers an exception.
-- Testcase --
{%
require("test");
%}
-- End --
-- Expect stderr --
Runtime error: No module named 'test' could be found
In line 2, byte 16:
` require("test");`
Near here --------^
-- End --
A compilation error in the module triggers an exception.
-- Testcase --
{%
push(REQUIRE_SEARCH_PATH, TESTFILES_PATH + '/*.uc');
require("require.test.broken");
%}
-- End --
-- File require/test/broken.uc --
// Unclosed object to force syntax error
return {
-- End --
-- Expect stderr --
Runtime error: Unable to compile source file './files/require/test/broken.uc':
| Syntax error: Expecting label
| In line 2, byte 10:
|
| `return {`
| ^-- Near here
In line 4, byte 31:
` require("require.test.broken");`
Near here -----------------------^
-- End --
|