- Notifications
You must be signed in to change notification settings - Fork 249
/
Copy pathtest-examples.mjs
124 lines (108 loc) · 3.91 KB
/
test-examples.mjs
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
importglobfrom"glob";
importfsfrom"fs";
importchild_processfrom"child_process";
importpathfrom"path";
import{URL}from'url';
constpathname=newURL('.',import.meta.url).pathname;
const__dirname=process.platform!=='win32' ? pathname : pathname.substring(1)
lettempFileName=path.join(__dirname,'..','_tempFile.res')
lettempFileNameRegex=/_tempFile\.res/g
// TODO: In the future we need to use the appropriate rescript version for each doc version variant
// see the package.json on how to define another rescript version
letcompilersDir=path.join(__dirname,"..","compilers")
letbsc=path.join(compilersDir,'node_modules','rescript-1110',process.platform,'bsc.exe');
letrescriptBin=path.join(compilersDir,'node_modules','rescript-1110','rescript');
letrescriptCoreCompiled=path.join(compilersDir,'node_modules','@rescript','core','lib','ocaml');
letrescriptReactCompiled=path.join(compilersDir,'node_modules','@rescript','react','lib','ocaml');
constprepareCompilers=()=>{
if(fs.existsSync(bsc)){
return;
}
console.log("compilers not installed. Installing compilers...");
child_process.execFileSync("npm",['install'],{cwd: compilersDir})
}
constprepareDependencies=()=>{
if(fs.existsSync(rescriptCoreCompiled)&&fs.existsSync(rescriptReactCompiled)){
return;
}
console.log("Dependencies not installed. Installing...");
child_process.execFileSync(rescriptBin,[],{cwd: compilersDir})
}
letparseFile=content=>{
if(!/```res(example|prelude|sig)/.test(content)){
return
}
letinCodeBlock=false
letmoduleId=0
returncontent.split('\n').map(line=>{
letmodifiedLine=''
if(line.startsWith('```res example')){
inCodeBlock=true
modifiedLine=`/* _MODULE_EXAMPLE_START */ module M_${moduleId++} = {`
}elseif(line.startsWith('```res prelude')){
inCodeBlock=true
modifiedLine=`/* _MODULE_PRELUDE_START */ include {`
}elseif(line.startsWith('```res sig')){
inCodeBlock=true
modifiedLine=`/* _MODULE_SIG_START */ module type M_${moduleId++} = {`
}elseif(inCodeBlock){
if(line.startsWith('```')){
inCodeBlock=false
modifiedLine='} // _MODULE_END'
}else{
modifiedLine=line
}
}
returnmodifiedLine
}).join('\n')
}
letpostprocessOutput=(file,error)=>{
returnerror.stderr.toString()
.replace(tempFileNameRegex,path.relative('.',file))
.replace(/\/\*_MODULE_(EXAMPLE|PRELUDE|SIG)_START\*\/.+/g,(_,capture)=>{
return'```res '+(capture==='EXAMPLE' ? 'example' : capture==='PRELUDE' ? 'prelude' : 'sig')
})
.replace(/(.*)\}(.*)\/\/_MODULE_END/g,(_,cap1,cap2)=>{
// cap1 cap2 might be empty or ansi coloring code
returncap1+'```'+cap2
})
}
prepareCompilers();
prepareDependencies();
console.log("Running tests...")
fs.writeFileSync(tempFileName,'')
letsuccess=true
glob.sync(__dirname+'/../pages/docs/{manual/latest,react/latest}/**/*.mdx').forEach((file)=>{
letcontent=fs.readFileSync(file,{encoding: 'utf-8'})
letparsedResult=parseFile(content)
if(parsedResult!=null){
fs.writeFileSync(tempFileName,parsedResult)
try{
// -109 for suppressing `Toplevel expression is expected to have unit type.`
// Most doc snippets do e.g. `Belt.Array.length(["test"])`, which triggers this
child_process.execFileSync(
bsc,
[
tempFileName,
'-I',
rescriptCoreCompiled,
'-I',
rescriptReactCompiled,
'-bs-jsx',
'4',
'-w',
'-109',
'-uncurried',
'-open',
'RescriptCore',
],
{stdio: "pipe"}
);
}catch(e){
process.stdout.write(postprocessOutput(file,e))
success=false
}
}
})
fs.unlinkSync(tempFileName)
process.exit(success ? 0 : 1)