Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80760 views
1
#! /usr/bin/env node
2
3
var U = require("../tools/node");
4
var path = require("path");
5
var fs = require("fs");
6
var assert = require("assert");
7
var sys = require("util");
8
9
var tests_dir = path.dirname(module.filename);
10
11
run_compress_tests();
12
13
/* -----[ utils ]----- */
14
15
function tmpl() {
16
return U.string_template.apply(this, arguments);
17
}
18
19
function log() {
20
var txt = tmpl.apply(this, arguments);
21
sys.puts(txt);
22
}
23
24
function log_directory(dir) {
25
log("*** Entering [{dir}]", { dir: dir });
26
}
27
28
function log_start_file(file) {
29
log("--- {file}", { file: file });
30
}
31
32
function log_test(name) {
33
log(" Running test [{name}]", { name: name });
34
}
35
36
function find_test_files(dir) {
37
var files = fs.readdirSync(dir).filter(function(name){
38
return /\.js$/i.test(name);
39
});
40
if (process.argv.length > 2) {
41
var x = process.argv.slice(2);
42
files = files.filter(function(f){
43
return x.indexOf(f) >= 0;
44
});
45
}
46
return files;
47
}
48
49
function test_directory(dir) {
50
return path.resolve(tests_dir, dir);
51
}
52
53
function as_toplevel(input) {
54
if (input instanceof U.AST_BlockStatement) input = input.body;
55
else if (input instanceof U.AST_Statement) input = [ input ];
56
else throw new Error("Unsupported input syntax");
57
var toplevel = new U.AST_Toplevel({ body: input });
58
toplevel.figure_out_scope();
59
return toplevel;
60
}
61
62
function run_compress_tests() {
63
var dir = test_directory("compress");
64
log_directory("compress");
65
var files = find_test_files(dir);
66
function test_file(file) {
67
log_start_file(file);
68
function test_case(test) {
69
log_test(test.name);
70
var options = U.defaults(test.options, {
71
warnings: false
72
});
73
var cmp = new U.Compressor(options, true);
74
var expect = make_code(as_toplevel(test.expect), false);
75
var input = as_toplevel(test.input);
76
var input_code = make_code(test.input);
77
var output = input.transform(cmp);
78
output.figure_out_scope();
79
output = make_code(output, false);
80
if (expect != output) {
81
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
82
input: input_code,
83
output: output,
84
expected: expect
85
});
86
}
87
}
88
var tests = parse_test(path.resolve(dir, file));
89
for (var i in tests) if (tests.hasOwnProperty(i)) {
90
test_case(tests[i]);
91
}
92
}
93
files.forEach(function(file){
94
test_file(file);
95
});
96
}
97
98
function parse_test(file) {
99
var script = fs.readFileSync(file, "utf8");
100
var ast = U.parse(script, {
101
filename: file
102
});
103
var tests = {};
104
var tw = new U.TreeWalker(function(node, descend){
105
if (node instanceof U.AST_LabeledStatement
106
&& tw.parent() instanceof U.AST_Toplevel) {
107
var name = node.label.name;
108
tests[name] = get_one_test(name, node.body);
109
return true;
110
}
111
if (!(node instanceof U.AST_Toplevel)) croak(node);
112
});
113
ast.walk(tw);
114
return tests;
115
116
function croak(node) {
117
throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
118
file: file,
119
line: node.start.line,
120
col: node.start.col,
121
code: make_code(node, false)
122
}));
123
}
124
125
function get_one_test(name, block) {
126
var test = { name: name, options: {} };
127
var tw = new U.TreeWalker(function(node, descend){
128
if (node instanceof U.AST_Assign) {
129
if (!(node.left instanceof U.AST_SymbolRef)) {
130
croak(node);
131
}
132
var name = node.left.name;
133
test[name] = evaluate(node.right);
134
return true;
135
}
136
if (node instanceof U.AST_LabeledStatement) {
137
assert.ok(
138
node.label.name == "input" || node.label.name == "expect",
139
tmpl("Unsupported label {name} [{line},{col}]", {
140
name: node.label.name,
141
line: node.label.start.line,
142
col: node.label.start.col
143
})
144
);
145
var stat = node.body;
146
if (stat instanceof U.AST_BlockStatement) {
147
if (stat.body.length == 1) stat = stat.body[0];
148
else if (stat.body.length == 0) stat = new U.AST_EmptyStatement();
149
}
150
test[node.label.name] = stat;
151
return true;
152
}
153
});
154
block.walk(tw);
155
return test;
156
};
157
}
158
159
function make_code(ast, beautify) {
160
if (arguments.length == 1) beautify = true;
161
var stream = U.OutputStream({ beautify: beautify });
162
ast.print(stream);
163
return stream.get();
164
}
165
166
function evaluate(code) {
167
if (code instanceof U.AST_Node)
168
code = make_code(code);
169
return new Function("return(" + code + ")")();
170
}
171
172