Skip to content

Latest commit

 

History

History
230 lines (173 loc) · 9.1 KB

CONTRIBUTING.md

File metadata and controls

230 lines (173 loc) · 9.1 KB

Contributing to FontoXPath

👍🎉 First off, thanks for showing interest in contributing to FontoXPath!🎉👍

The XPath/XQuery engine is not yet complete, though we are striving to the highest grade of usability. This means that functions get to be implemented as soon as we want to use them. The XPath 3.1 spec and the accompanying XPath functions spec are quite large and intricate and we do not have nearly enough time to implement all of it. We would love some help from you!

Here are some important resources:

Creating an issue

So you've found a bug, a missing feature or you have some feedback. Great! We appreciate an issue for it on the GitHub repository. If the issue is a request for a feature, we will implement it when we get to it, but a pull request would very much speed things up.

Creating a pull request

Wow, you actually want to help!? Even better! FontoXPath is a fun project to work on, with a lot of hard puzzles which were tricky to solve and even more puzzles lurking in the deep. But do not worry, we are here to help in any possible way.

Setting up a development environment

To set up the tests on UNIX:

./test/install-assets.sh

Or on Windows:

./test/install-assets.ps1

To run the tests:

npm run test
# Or
npm run qt3tests
# Or
npm run xqutstests

FontoXPath is written in TypeScript, which is transformed to JavaScript using tsickle and compiled with the Google Closure Compiler for an optimized build.

Running the XML Query Test suite (QT3) requires a recent version of the QT3 test set to be installed at ./test/assets/qt3tests. It is a submodule that should be cloned. Running the tests for XQuery Update Facility requires a recent version of the XQUTS test set to be installed at ./test/assets/XQUTS. There exists a mirror here.

FontoXPath uses XQueryX as a parser format, this can be tested using the XQueryX test set which is included in the QT3 test set. To be able to run these tests, extract the xqueryx.zip file to the test/assets/QT3/xqueryx folder.

Implementing a missing XPath function

XPath functions are an ideal place to start off as a first pull request. They usually only require some local changes and the spec is very readable and clear on the intended behaviour. The specification can be found here. The QT3 test set set usually contains tests which cover the function.

If you run into any problems when implementing what you want, do not hesitate to ask for help. Just make the pull request with whatever you have at that moment and we are happy to assist you in any difficulties!

The XPath functions are usually located in the src/expressions/functions folder. Just add them to the file that has the most to do with the function you'd like to implement.

Data structures

FontoXPath uses lazy evaluation. This means the main data structure (Sequence) is basically a generator. It has a number of functions which can easily get the first item, all items, the effective boolean value, etc. We tend to use the methods like first(), length(), mapCases() and map() for new code. The array functions located at src/expressions/functions/builtInFunctions.arrays.ts are a good example for new functions.

An iteration item (obtained by iterating over Sequence#value) can have three forms:

  • { done: false, value: <any> }: We have a value.
  • { done: true }: We are done iterating.

Debugging

You can run a demo page (http://localhost:8080) which can be used for debugging. This page is in its own subpackage in the demo folder. This page aims to do as little code transpilation as possible in order to make debugging easy. Run it by cd-ing into it, running npm install, followed by an npm start.

This script runs the typescript compiler in watch mode and serves a simple test application.

Running the tests

FontoXPath contains different test sets:

Tests Run command
The unit tests npm run test
The QT3 tests npm run qt3tests
The QT3 XQueryX tests npm run qt3testsxqueryx
The XQUTS tests npm run xqutstests
The XQUTS XQueryX tests npm run xqutstestsxqueryx

They all run in Node. By running the tests with the --inspect flag, they can be debugged by the browser: npm run test -- --inspect --inspect-brk. The tests can also be executed with the built version of fontoxpath. Use the --dist flag to do so: npm run qt3test -- --dist. The unit tests can be executed using npm run integrationtests

The JavaScript unit tests can be used while developing, since they run quite fast. The other tests can be used to verify your implementation but they are quite slow. Running all of them will likely take several minutes.

New JavaScript tests can be added to a *.tests.ts file somewhere in the test/specs folder. Try to add a new test in a file with tests about similar functions.

If you want to create a new test file, it should be placed in thetest/specs/expressions folder if the tests can only be ran against the unminified code. If they do not require minified code (ie. use only public, external API, they can be placed in the test/specs/parsing folder.

If you expect new tests to succeed run npm run alltests -- --regenerate, this will update the csv files which contain failing tests. Use git to find differences.

If you are adding a new feature, don't forget to edit the file test/runnableTestSets.csv. This file disables tests for features we have not yet implemented.

If you want to have a overview of the tests supported by the JavaScript codegen, run the qt3tests with the tag: --reportcodegencases. If you want a test to fail when it isn't supported by the codegen run the qt3tests with the tag: --forcecodegen.

Running benchmarks

FontoXPath has 2 options to run benchmarks.

In one we run benchmarks over scenarios defined in javascript which are located in the directory /performance. These can be run using fonto-benchmark-runner commands which will run the benchmarks in the console. Note that some tests use assets from the QT3TS, see the steps in Setting up a development environment.

To check the performance of fontoxpath with the qt3tests, we pick a random subset of the qt3tests as running all will take too long (hours). This random subset is not checked in but can be generated using npm run qt3performance -- --regenerate [<number-of-tests>], this will create and populate test/runnablePerformanceTestNames.csv. You can manually edit this file to run specific tests. By storing these in a file you can run the same set even when switching between different commits. With the generated file present you can run the tests using npm run qt3performance, this will run a benchmark for each qt3 test using benchmarkjs.

Running the fuzzer

FontoXPath comes with a fuzzer that can find bugs automatically. The fuzzer has a corpus of ~200 XPath expressions which are randomly mutated.

To run the fuzzer, run the following command in the root of this repository:

npm run fuzzer

The fuzzer is located in the ./fuzzer/ directory. The fuzzer is split across several components:

  1. fuzzer.ts - provides abstractions to support different type of fuzzer implementations.
  2. engine.ts - contains the runner which scales, monitors and reports progress of a fuzzer.
  3. corpus_based_fuzzer.ts - well, the name says it all.
  4. index.ts - main entry point for the npm run fuzzer command, currently executes a CorpusBasedFuzzer with the iso_corpus.ts.

Building

When the new function seems to work, you can make a build of FontoXPath. Use the command npm run build to make one. The Closure Compiler may warn about some code constructs. They are usually easy to fix. If you are running into any problems, do not hesitate to ask for help!

The build can be double-checked using:

npm run qt3tests -- --dist
npm run qt3testsxqueryx -- --dist
npm run xqutstests -- --dist
npm run xqutstestsxqueryx -- --dist

The build does not have to be checked in.

Publishing

First and foremost, you'll need to have publish access to the FontoXPath NPM repository. If you have that, you can publish using the following steps:

npm version (major|minor|patch|prerelease);
git push;
git push --tags;
npm publish;