Let's get everything setup to develop on Quadratic!
First, follow the instructions to install:
Start Docker Desktop after installing required software. Now install the depedencies:
# install node version 18
nvm install 18
#install the WASM toolchain
rustup target add wasm32-unknown-unknown
# install cargo watch
cargo install cargo-watch
First, copy over the example file:
cp .env.example .env.local
Enter the missing Auth0 values and save.
Now that dependencies are installed, all you need to do is run node dev
to
bring up the all services. Invoke node run --help
for information on how
to use this script, as you can use it to watch individual (or groups of)
services during development. See the Using node dev section
for more more information.
Docker Compose is a utility that's built into Docker Desktop and is a compact
infrastructure-as-code framework. Services (e.g. running Docker containers) are
defined, along with configuration information, in the docker-compose.yml
file.
Services can talk to each other and can communicate with services in the user's host
network.
To pull up the Docker network with just the required depedencies (Redis, Postgres, Localstack):
npm run docker:up
Along with the dependent services, scripts are executed that create S3 buckets and migrate the database. Docker is run in the background in this script.
To build images for individual services (from project root):
docker-compose build quadratic-api
docker-compose build quadratic-files
docker-compose build quadratic-multiplayer
You can also develop Quadratic without using docker
- Set up .env in quadratic-client, quadratic-api, quadratic-multiplayer, and quadratic-files.
cp .env.example .env.local
cp quadratic-client/.env_example quadratic-client/.env.local
cp quadratic-api/.env_example quadratic-api/.env
cp quadratic-multiplayer/.env.example quadratic-multiplayer/.env
cp quadratic-files/.env.example quadratic-files/.env
brew install postgresql
(Mac)
brew services start postgresql
- Create a database for use with postgres
- Add database to quadratic-api/.env
brew install redis
brew services start redis
Call node dev
from the /quadratic directory. This script handles fixing most common problems. You do need to ensure your system is properly set up with the correct .env
files and the database and redis setup and available.
Usage: node dev [options]
Runs the Quadratic dev server. By default, only React runs in watch mode.
Options:
-a, --api Watch the quadratic-api directory
-c, --core Watch the quadratic-core directory
-m, --multiplayer Watch the quadratic-multiplayer directory
-f, --files Watch the quadratic-files directory
-a, --all Watch all directories
-s, --skipTypes Skip WASM types compilation
-p, --perf Run quadratic-core in perf mode (slower to link but faster runtime)
-R, --hideReact Hide React output
-A, --hideAPI Hide React output
-C, --hideCore Hide React output
-T, --hideTypes Hide Types output
-M, --hideMultiplayer Hide Multiplayer output
-F, --hideFiles Hide Files output
-d, --dark Use dark theme
-h, --help display help for command
Press h
while running to see this help menu. Press H
while running to see the CLI commands.
Press:
a c m f - Toggle watch for component
R A C T M F - Toggle showing logs for component
p - Toggle performance build for Core
r - Restart React
t - Rebuild WASM types from Core for React
d - Toggle dark theme
H - Show CLI options
After you successfully run the app the first time, use node dev -ACTMF
if only developing in React. This will hide output from Rust and server components.
To test quadratic-client, enter the following command from the root of the project:
npm run test:ts
To test quadratic-api, close the existing docker network (npm run docker:down
), and enter the following command from the root of the project:
npm run test:api
To test an individual crate, bring up the docker network (npm run docker:up
) and navigate to the root of the crate and enter:
cargo test
# npm alternative
npm run test
# watcher
RUST_LOG=info cargo watch -x 'test'
# npm alternative
npm run test:watch
Alternatively, to run all rust test, simply enter cargo test
at the project root.
See the README in each crate for more information.
In CI, coverage is automatically collected and sent to CodeCov.
For local coverage information, you'll need to install some dependencies first:
cargo install grcov
rustup component add llvm-tools-preview
To run coverage and generate HTML reports, bring up the docker network
(npm run docker:up
) and navigate to the individual crate and enter:
npm run coverage
Coverage infomration will be available in the generated coverage
folder located at coverage/html/index.html
.
To lint an individual crate, navigate to the root of the crate and enter:
cargo clippy --all-targets --all-features -- -D warnings
# npm alternative
npm run lint
Alternatively, to run all rust test, simply enter cargo clippy --all-targets --all-features -- -D warnings
at the project root.
Local load testing is performed by JMeter. First, install JMeter by either downloading it it or installing via your favorite package manager (e.g. brew):
brew install jmeter
Load tests are located in the /tests/load
directory. Run run jmeter:
bash jmeter
# or for some
bash /opt/homebrew/Cellar/jmeter/5.6.3/bin/jmeter
Select file -> open
and navigate to the /tests/load
directory and pick a load test file to edit. See the user manual for more information.
To run a jmter test, bring up all relevant services and invoke:
bash jmeter -n -t PATH_TO_JMX_FILE
# alternative if you're having issues locating your JDK
JAVA_HOME="/opt/homebrew/opt/openjdk" bash /opt/homebrew/Cellar/jmeter/5.6.3/libexec/bin/jmeter -n -t test/load/load-test-quadratic-multiplayer.jmx
Output will be located in the terminal.
The current version numbers are stored in updateAlertVersion.json
. This JSON is ready by both the client and the multiplayer server. When the client has a lower version number then the multiplayer (the version is sent by the multiplayer server with the EnterFileRoom message), then the user is prompted to refresh with slightly different experience based on required vs. recommended changes.