Initial attempt at docker compliance tests.
This commit is contained in:
59
js/README.md
Normal file
59
js/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
Compliance Tests
|
||||
================
|
||||
|
||||
These tests run my implementation of LinkedIn's Dust and the official implementation of [LinkedIn's DustJS](https://www.dustjs.com) as compares the output to ensure they match.
|
||||
|
||||
Running in Docker
|
||||
=================
|
||||
|
||||
Go to the root directory of this repository where there is a `Dockerfile` and run:
|
||||
|
||||
``` sh
|
||||
docker build -t duster . && docker run --rm -i -t duster
|
||||
```
|
||||
|
||||
This command will run through the test cases in `js/test_cases`, comparing the output of the official LinkedIn DustJS implementation against the output of the `duster` implementation. If there are any differences, it will flag the test as a failure.
|
||||
|
||||
The tests have a structure of:
|
||||
|
||||
``` text
|
||||
test_cases
|
||||
└── hello_world
|
||||
├── input1.json
|
||||
├── input2.json
|
||||
├── main.dust
|
||||
└── partial.dust
|
||||
```
|
||||
|
||||
The folder name `hello_world` is the name of the test group. For each test group there must be a file named `main.dust`. This file will be the top-level template that gets rendered. All other `*.dust` files will get registered into the dust rendering context as partials, with the same name as their file excluding the file extension. For example, `main.dust` could invoke `partial.dust` with `{>partial/}`. Each `*.json` file is a separate context that will be passed into the dust renderer, making each `*.json` file form a test inside the test group.
|
||||
|
||||
Running Manually
|
||||
================
|
||||
|
||||
Individually
|
||||
------------
|
||||
|
||||
If you want to invoke the LinkedIn DustJS manually, the `dustjs_shim` expects the json context to be passed in over stdin, and a list of templates to be passed in as arguments, with the first argument serving as the main template. An example invocation from this folder would therefore be:
|
||||
|
||||
``` sh
|
||||
npm install dustjs-linkedin
|
||||
cat test_cases/hello_world/input1.json | node dustjs_shim.js test_cases/hello_world/main.dust
|
||||
```
|
||||
|
||||
Unlike the docker variant, there is no requirement for the template to be named `main.dust` since it will render the first argument as the main template. Running the same test case through the `duster` implementation would be:
|
||||
|
||||
``` sh
|
||||
npm install dustjs-linkedin
|
||||
cat test_cases/hello_world/input1.json | ../target/debug/duster-cli test_cases/hello_world/main.dust
|
||||
```
|
||||
|
||||
Batch
|
||||
-----
|
||||
|
||||
If you instead would like to run the entire compliance test suite manually outside of docker, you can run:
|
||||
|
||||
``` sh
|
||||
npm install dustjs-linkedin
|
||||
(cd .. && cargo build)
|
||||
./run_compliance_suite.bash
|
||||
```
|
||||
36
js/dustjs_shim.js
Normal file
36
js/dustjs_shim.js
Normal file
@@ -0,0 +1,36 @@
|
||||
var dust = require('dustjs-linkedin');
|
||||
var fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
var argv = process.argv.slice(2);
|
||||
if (argv.length < 1) {
|
||||
console.error("Expecting only 1 argument (a path to a template)");
|
||||
process.exit(1);
|
||||
}
|
||||
var context = JSON.parse(fs.readFileSync(0, 'utf-8'));
|
||||
var main_template = path.parse(argv[0])["name"];
|
||||
|
||||
for (var i = 0, len = argv.length; i < len; ++i) {
|
||||
var filename = path.parse(argv[i])["name"];
|
||||
|
||||
try {
|
||||
var template_source = fs.readFileSync(argv[i], 'utf-8');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var compiled_template = dust.compile(template_source, filename);
|
||||
dust.loadSource(compiled_template);
|
||||
|
||||
}
|
||||
|
||||
dust.render(main_template, context, function(err, out) {
|
||||
if(err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log(out);
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
34
js/run_compliance_suite.bash
Executable file
34
js/run_compliance_suite.bash
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Runs the full suite of tests against LinkedIn DustJS and duster to compare the result
|
||||
set -uo pipefail
|
||||
IFS=$'\n\t'
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
failed_count=0
|
||||
|
||||
find "$DIR/test_cases" -maxdepth 1 -mindepth 1 -type d | sort | while read test_group; do
|
||||
failed_count_in_group=0
|
||||
test_group_name=$(basename "$test_group")
|
||||
find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.json' | sort | while read test_case; do
|
||||
failed_count_in_testcase=0
|
||||
test_case_file_name=$(basename "$test_case")
|
||||
test_case_name=${test_case_file_name%.*}
|
||||
(
|
||||
if cmp --quiet <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust') node dustjs_shim.js < "$test_case") <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust') ../target/debug/duster-cli < "$test_case"); then
|
||||
echo "$test_group_name::$test_case_name PASSED"
|
||||
else
|
||||
echo "$test_group_name::$test_case_name FAILED"
|
||||
diff <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust') node dustjs_shim.js < "$test_case") <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust') ../target/debug/duster-cli < "$test_case")
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
if [ $? -ne 0 ]; then
|
||||
failed_count_in_testcase=$((failed_count_in_testcase + 1))
|
||||
fi
|
||||
echo "testcase failed $failed_count_in_testcase"
|
||||
done
|
||||
echo "group failed: $failed_count_in_group"
|
||||
done
|
||||
|
||||
echo "total failed $failed_count"
|
||||
1
js/test_cases/hello_world/input1.json
Normal file
1
js/test_cases/hello_world/input1.json
Normal file
@@ -0,0 +1 @@
|
||||
{"name": "Bob"}
|
||||
1
js/test_cases/hello_world/input2.json
Normal file
1
js/test_cases/hello_world/input2.json
Normal file
@@ -0,0 +1 @@
|
||||
{"name": "Alice"}
|
||||
1
js/test_cases/hello_world/main.dust
Normal file
1
js/test_cases/hello_world/main.dust
Normal file
@@ -0,0 +1 @@
|
||||
Hello {name}!
|
||||
Reference in New Issue
Block a user