Merge branch 'docker_compliance_tests' into render

master
Tom Alexander 4 years ago
commit aa24f50dfa
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

@ -0,0 +1,26 @@
FROM rustlang/rust:nightly-alpine3.10
# findutils needed to replace busybox xargs because it is failing to
# pass stdin through when using the `-a` flag
RUN apk --no-cache add bash git npm nodejs findutils
# Create unprivileged user
RUN addgroup -S duster && adduser -S duster -G duster
# Install LinkedIn DustJS. Installing it globally before copying in
# the repo to avoid spamming the npm servers with every codebase
# change.
RUN npm install -g dustjs-linkedin
# Copy repo into duster user's directory
RUN mkdir /home/duster/duster
WORKDIR /home/duster/duster
COPY . .
RUN chown -R duster:duster /home/duster/duster
USER duster
RUN git clean -dfxq
RUN cargo build
RUN npm link dustjs-linkedin
CMD /home/duster/duster/js/run_compliance_suite.bash

@ -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
```

@ -0,0 +1,58 @@
#!/usr/bin/env bash
#
# Runs the full suite of tests against LinkedIn DustJS and duster to compare the result
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
failed_count=0
show_diff=0
while (( "$#" )); do
if [ "$1" = "--help" ]; then
cat<<EOF
Runs the full compliance test suite.
Options:
--show-diff Shows the difference between the two dust implementations
EOF
exit 0
elif [ "$1" = "--show-diff" ]; then
show_diff=1
else
(>&2 echo "Unrecognized option: $1")
exit 1
fi
shift
done
while read -r test_group; do
test_group_name=$(basename "$test_group")
while read -r test_case; do
test_case_file_name=$(basename "$test_case")
test_case_name=${test_case_file_name%.*}
set +e
(
if cmp -s <(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 "$DIR/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') "$DIR/../target/debug/duster-cli" < "$test_case"); then
echo "$test_group_name::$test_case_name PASSED"
else
echo "$test_group_name::$test_case_name FAILED"
if [ $show_diff -eq 1 ]; then
diff --label "dustjs-linked" --label "duster" <(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 "$DIR/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') "$DIR/../target/debug/duster-cli" < "$test_case")
fi
exit 1
fi
)
if [ $? -ne 0 ]; then
failed_count=$((failed_count + 1))
fi
set -e
done <<<"$(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.json' | sort)"
done <<<"$(find "$DIR/test_cases" -maxdepth 1 -mindepth 1 -type d | sort)"
if [ $failed_count -ne 0 ]; then
echo "$failed_count failed tests"
exit 1
else
echo "All tests passed"
fi

@ -1,11 +0,0 @@
* 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.
** Setup
Install LinkedIn's DustJS in order to rust the compliance tests
** Running
The dustjs_shim expects a path to a template file as the first parameter, and it expects a json context over stdin. For example, to invoke it on the command line you could run:
```sh
cat test_cases/hello_world/input1.json | node dustjs_shim.js test_cases/hello_world/main.dust
```
Each template will be compiled with the same name as the file without the file extension (so main.dust will be compiled as "main"). THe shim renders the first template passed into it (all the others can be accessed as partials).
Loading…
Cancel
Save