1 /* strict mode compliance: ensure that global variabes are defined */ 2 if (!exists(global, 'REQUIRE_SEARCH_PATH')) 3 global.MOCK_SEARCH_PATH = null; 4 5 if (!exists(global, 'MOCK_SEARCH_PATH')) 6 global.MOCK_SEARCH_PATH = null; 7 8 if (!exists(global, 'TRACE_CALLS')) 9 global.TRACE_CALLS = null; 10 11 let _fs = require("fs"); 12 13 /* Force reloading fs module on next require */ 14 delete global.modules.fs; 15 16 let _log = (level, fmt, ...args) => { 17 let color, prefix; 18 19 switch (level) { 20 case 'info': 21 color = 34; 22 prefix = '!'; 23 break; 24 25 case 'warn': 26 color = 33; 27 prefix = 'W'; 28 break; 29 30 case 'error': 31 color = 31; 32 prefix = 'E'; 33 break; 34 35 default: 36 color = 0; 37 prefix = 'I'; 38 } 39 40 let f = sprintf("\u001b[%d;1m[%s] %s\u001b[0m", color, prefix, fmt); 41 warn(replace(sprintf(f, ...args), "\n", "\n "), "\n"); 42 }; 43 44 let read_data_file = (path) => { 45 for (let dir in MOCK_SEARCH_PATH) { 46 let fd = _fs.open(dir + '/' + path, "r"); 47 48 if (fd) { 49 let data = fd.read("all"); 50 fd.close(); 51 52 return data; 53 } 54 } 55 56 return null; 57 }; 58 59 let read_json_file = (path) => { 60 let data = read_data_file(path); 61 62 if (data != null) { 63 try { 64 return json(data); 65 } 66 catch (e) { 67 _log('error', "Unable to parse JSON data in %s: %s", path, e); 68 69 return NaN; 70 } 71 } 72 73 return null; 74 }; 75 76 let format_json = (data) => { 77 let rv; 78 79 let format_value = (value) => { 80 switch (type(value)) { 81 case "object": 82 return sprintf("{ /* %d keys */ }", length(value)); 83 84 case "array": 85 return sprintf("[ /* %d items */ ]", length(value)); 86 87 case "string": 88 if (length(value) > 64) 89 value = substr(value, 0, 64) + "..."; 90 91 /* fall through */ 92 return sprintf("%J", value); 93 94 default: 95 return sprintf("%J", value); 96 } 97 }; 98 99 switch (type(data)) { 100 case "object": 101 rv = "{"; 102 103 let k = sort(keys(data)); 104 105 for (let i, n in k) 106 rv += sprintf("%s %J: %s", i ? "," : "", n, format_value(data[n])); 107 108 rv += " }"; 109 break; 110 111 case "array": 112 rv = "["; 113 114 for (let i, v in data) 115 rv += (i ? "," : "") + " " + format_value(v); 116 117 rv += " ]"; 118 break; 119 120 default: 121 rv = format_value(data); 122 } 123 124 return rv; 125 }; 126 127 let trace_call = (ns, func, args) => { 128 let msg = "[call] " + 129 (ns ? ns + "." : "") + 130 func; 131 132 for (let k, v in args) { 133 msg += ' ' + k + ' <'; 134 135 switch (type(v)) { 136 case "array": 137 case "object": 138 msg += format_json(v); 139 break; 140 141 default: 142 msg += v; 143 } 144 145 msg += '>'; 146 } 147 148 switch (TRACE_CALLS) { 149 case '1': 150 case 'stdout': 151 _fs.stdout.write(msg + "\n"); 152 break; 153 154 case 'stderr': 155 _fs.stderr.write(msg + "\n"); 156 break; 157 } 158 }; 159 160 /* Prepend mocklib to REQUIRE_SEARCH_PATH */ 161 for (let pattern in REQUIRE_SEARCH_PATH) { 162 /* Only consider ucode includes */ 163 if (!match(pattern, /\*\.uc$/)) 164 continue; 165 166 let path = replace(pattern, /\*/, 'mocklib'), 167 stat = _fs.stat(path); 168 169 if (!stat || stat.type != 'file') 170 continue; 171 172 if (type(MOCK_SEARCH_PATH) != 'array' || length(MOCK_SEARCH_PATH) == 0) 173 MOCK_SEARCH_PATH = [ replace(path, /mocklib\.uc$/, '../mocks') ]; 174 175 unshift(REQUIRE_SEARCH_PATH, replace(path, /mocklib\.uc$/, 'mocklib/*.uc')); 176 break; 177 } 178 179 if (type(MOCK_SEARCH_PATH) != 'array' || length(MOCK_SEARCH_PATH) == 0) 180 MOCK_SEARCH_PATH = [ './mocks' ]; 181 182 let _print = global.print; 183 184 /* Register global mocklib namespace */ 185 global.mocklib = { 186 require: function(module) { 187 let path, res, ex; 188 189 if (type(REQUIRE_SEARCH_PATH) == "array" && index(REQUIRE_SEARCH_PATH[0], 'mocklib/*.uc') != -1) 190 path = shift(REQUIRE_SEARCH_PATH); 191 192 try { 193 res = require(module); 194 } 195 catch (e) { 196 ex = e; 197 } 198 199 if (path) 200 unshift(REQUIRE_SEARCH_PATH, path); 201 202 if (ex) 203 die(ex); 204 205 return res; 206 }, 207 208 I: (...args) => _log('info', ...args), 209 N: (...args) => _log('notice', ...args), 210 W: (...args) => _log('warn', ...args), 211 E: (...args) => _log('error', ...args), 212 213 format_json, 214 read_data_file, 215 read_json_file, 216 trace_call 217 }; 218 219 /* Override stdlib functions */ 220 global.system = function(argv, timeout) { 221 trace_call(null, "system", { command: argv, timeout }); 222 223 return 0; 224 }; 225 226 global.time = function() { 227 trace_call(null, "time"); 228 229 return 1615382640; 230 }; 231 232 global.print = function(...args) { 233 if (length(args) == 1 && type(args[0]) in ["array", "object"]) 234 printf("%s\n", format_json(args[0])); 235 else 236 _print(...args); 237 }; 238 239 return global.mocklib; 240
This page was automatically generated by LXR 0.3.1. • OpenWrt