2 /* strict mode compliance: ensure that global variabes are defined */
3 if (!exists(global, 'REQUIRE_SEARCH_PATH'))
4 global.MOCK_SEARCH_PATH = null;
6 if (!exists(global, 'MOCK_SEARCH_PATH'))
7 global.MOCK_SEARCH_PATH = null;
9 if (!exists(global, 'TRACE_CALLS'))
10 global.TRACE_CALLS = null;
12 let _fs = require("fs");
14 /* Force reloading fs module on next require */
15 delete global.modules.fs;
17 let _log = (level, fmt, ...args) => {
41 let f = sprintf("\u001b[%d;1m[%s] %s\u001b[0m", color, prefix, fmt);
42 warn(replace(sprintf(f, ...args), "\n", "\n "), "\n");
45 let read_data_file = (path) => {
46 for (let dir in MOCK_SEARCH_PATH) {
47 let fd = _fs.open(dir + '/' + path, "r");
50 let data = fd.read("all");
60 let read_json_file = (path) => {
61 let data = read_data_file(path);
68 _log('error', "Unable to parse JSON data in %s: %s", path, e);
77 let format_json = (data) => {
80 let format_value = (value) => {
81 switch (type(value)) {
83 return sprintf("{ /* %d keys */ }", length(value));
86 return sprintf("[ /* %d items */ ]", length(value));
89 if (length(value) > 64)
90 value = substr(value, 0, 64) + "...";
93 return sprintf("%J", value);
96 return sprintf("%J", value);
100 switch (type(data)) {
104 let k = sort(keys(data));
107 rv += sprintf("%s %J: %s", i ? "," : "", n, format_value(data[n]));
115 for (let i, v in data)
116 rv += (i ? "," : "") + " " + format_value(v);
122 rv = format_value(data);
128 let trace_call = (ns, func, args) => {
129 let msg = "[call] " +
130 (ns ? ns + "." : "") +
133 for (let k, v in args) {
134 msg += ' ' + k + ' <';
139 msg += format_json(v);
149 switch (TRACE_CALLS) {
152 _fs.stdout.write(msg + "\n");
156 _fs.stderr.write(msg + "\n");
161 /* Prepend mocklib to REQUIRE_SEARCH_PATH */
162 for (let pattern in REQUIRE_SEARCH_PATH) {
163 /* Only consider ucode includes */
164 if (!match(pattern, /\*\.uc$/))
167 let path = replace(pattern, /\*/, 'mocklib'),
168 stat = _fs.stat(path);
170 if (!stat || stat.type != 'file')
173 if (type(MOCK_SEARCH_PATH) != 'array' || length(MOCK_SEARCH_PATH) == 0)
174 MOCK_SEARCH_PATH = [ replace(path, /mocklib\.uc$/, '../mocks') ];
176 unshift(REQUIRE_SEARCH_PATH, replace(path, /mocklib\.uc$/, 'mocklib/*.uc'));
180 if (type(MOCK_SEARCH_PATH) != 'array' || length(MOCK_SEARCH_PATH) == 0)
181 MOCK_SEARCH_PATH = [ './mocks' ];
183 let _print = global.print;
185 /* Register global mocklib namespace */
187 require: function(module) {
190 if (type(REQUIRE_SEARCH_PATH) == "array" && index(REQUIRE_SEARCH_PATH[0], 'mocklib/*.uc') != -1)
191 path = shift(REQUIRE_SEARCH_PATH);
194 res = require(module);
201 unshift(REQUIRE_SEARCH_PATH, path);
209 I: (...args) => _log('info', ...args),
210 N: (...args) => _log('notice', ...args),
211 W: (...args) => _log('warn', ...args),
212 E: (...args) => _log('error', ...args),
220 /* Override stdlib functions */
221 global.system = function(argv, timeout) {
222 trace_call(null, "system", { command: argv, timeout });
227 global.time = function() {
228 trace_call(null, "time");
233 global.print = function(...args) {
234 if (length(args) == 1 && type(args[0]) in ["array", "object"])
235 printf("%s\n", format_json(args[0]));
240 return global.mocklib;