From 35dd3d478ae65bc557f36e13d943f1d4d2be0b70 Mon Sep 17 00:00:00 2001 From: Feihong Hsu Date: Wed, 28 Feb 2024 14:32:39 +0100 Subject: [PATCH 1/2] Generate both reason and ocaml syntax docs --- .github/workflows/deploy.yml | 8 ++++---- .gitignore | 1 + CHANGES.md | 3 +++ Makefile | 25 ++++++++++++------------ README.md | 37 ++++++++++++++++++++++++++++++++---- docs/index.html | 20 +++++++++++++++++++ package.json | 4 ---- src/domloader.ml | 6 ++++-- src/fest.ml | 6 ++++++ test/bindings.ml | 5 +++-- test/components.re | 2 +- test/dune | 1 + 12 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 CHANGES.md create mode 100644 docs/index.html diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index be85c01..e03736c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,10 +4,10 @@ on: # Runs on pushes targeting the `master` branch. push: branches: - - master + - master schedule: # Prime the caches every Monday - - cron: 0 1 * * MON + - cron: 0 1 * * MON # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -38,7 +38,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 cache: npm - uses: ocaml/setup-ocaml@v2 with: @@ -55,6 +55,6 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./_build/default/_doc/_html + publish_dir: ./_docs enable_jekyll: false force_orphan: true diff --git a/.gitignore b/.gitignore index 4cc5143..1544d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules _build _opam +_docs dist/ .vscode diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..50b3b31 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,3 @@ +# Unreleased + +- Add bindings for `node:test` and `node:assert/strict` diff --git a/Makefile b/Makefile index df7d5a9..d1178d9 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ DUNE = opam exec -- dune .DEFAULT_GOAL := help +DUNE_BUILD_DIR := $(shell pwd)/_build + .PHONY: help help: ## Print this help message @echo "List of available make commands"; @@ -32,14 +34,6 @@ build: ## Build the project build_verbose: ## Build the project $(DUNE) build --verbose -.PHONY: serve -serve: ## Serve the application with a local HTTP server - npm run serve - -.PHONY: bundle -bundle: ## Bundle the JavaScript application - npm run bundle - .PHONY: clean clean: ## Clean build artifacts and other generated files $(DUNE) clean @@ -54,16 +48,23 @@ format-check: ## Checks if format is correct .PHONY: watch watch: ## Watch for the filesystem and rebuild on every change - $(DUNE) build --watch @react @node + $(DUNE) build --watch .PHONY: test test: ## Run test suite - $(DUNE) test --no-buffer + $(DUNE) build @runtest --no-buffer .PHONY: docs docs: ## Build the docs - $(DUNE) build @doc + rm -rf _docs + mkdir _docs + cp docs/index.html _docs + ODOC_SYNTAX=reason $(DUNE) build @doc + mv _build/default/_doc/_html/odoc.support _docs + mv _build/default/_doc/_html/melange-fest _docs/reason + ODOC_SYNTAX=ocaml $(DUNE) build @doc + mv _build/default/_doc/_html/melange-fest _docs/ocaml .PHONY: preview preview: docs ## Preview the docs - cd _build/default/_doc/_html/ && python -m http.server + cd _docs && python -m http.server diff --git a/README.md b/README.md index f506f13..972eaab 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,47 @@ # melange-fest -A minimal test framework for Melange using Node [test runner](https://nodejs.org/api/test.html). +A minimal test framework for Melange using [Node test +runner](https://nodejs.org/api/test.html). ## Quick Start -tbd +```reason +open Fest + +test("1+1=2", () => expect |> equal(1 + 1, 2)); +``` ### React React support is provided by [`reason-react`](https://github.com/reasonml/reason-react/). -More info tbd. +```reason +open Fest; +module RTL = ReactTestingLibrary; +[@mel.get] external textContent: Dom.element => string = "textContent"; + +Domloader.init(); + +module Hello = { + [@react.component] + let make = (~text) =>
{"Hello " ++ text |> React.string}
; +}; + +let () = + test("test component", () => { + let result = RTL.render(); + + // Check that Hello component renders the name properly. + let el = RTL.getByText(~matcher=`Str("Hello Nila"), result); + expect |> equal(textContent(el), "Hello Nila"); + }); +``` ## Commands -tbd +Run all tests: + +```bash +make test +``` diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..c2d3baf --- /dev/null +++ b/docs/index.html @@ -0,0 +1,20 @@ + + + + index + + + + + +
+
+

melange-fest documentation

+ +
+
+ + diff --git a/package.json b/package.json index d81791d..0c921e5 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,4 @@ { - "scripts": { - "bundle": "webpack --mode production --entry ./_build/default/src/output/src/ReactApp.js", - "serve": "webpack serve --open --mode development --entry ./_build/default/src/output/src/ReactApp.js" - }, "dependencies": { "@testing-library/react": "^14.0.0", "jsdom": "^22.1.0", diff --git a/src/domloader.ml b/src/domloader.ml index 3c7561c..3b771b8 100644 --- a/src/domloader.ml +++ b/src/domloader.ml @@ -1,5 +1,7 @@ -(* just here to allow other modules to load the raw code below *) -let init () = () +(** Initialize the Node environment to make it ready to run tests *) +let init () = + (* this function doesn't do anything, it just allows other modules to load the raw code below *) + () [%%mel.raw {| diff --git a/src/fest.ml b/src/fest.ml index 8eae60b..b71debb 100644 --- a/src/fest.ml +++ b/src/fest.ml @@ -1,3 +1,5 @@ +(** Bindings for functions from {{: https://nodejs.org/api/test.html#test-runner }node:test} and {{: https://nodejs.org/api/assert.html#strict-assertion-mode }node:assert/strict} modules *) + external test : string -> (unit -> unit) -> unit = "test" [@@mel.module "node:test"] (** Create a test with a given name and callback function that runs the test *) @@ -20,6 +22,10 @@ external expect : assertion = "node:assert/strict" [@@mel.module] (** The {{: https://nodejs.org/api/assert.html#strict-assertion-mode} node:assert/strict} module object *) +external ok : bool -> unit = "ok" +[@@mel.send.pipe: assertion] +(** Tests if the given value is true *) + external equal : 'a -> 'a -> unit = "strictEqual" [@@mel.send.pipe: assertion] (** Tests strict equality between the actual and expected parameters as determined by {{: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is }Object.is()} *) diff --git a/test/bindings.ml b/test/bindings.ml index 1f16ed8..a462c2f 100644 --- a/test/bindings.ml +++ b/test/bindings.ml @@ -1,7 +1,8 @@ open Fest -let () = test "equal" (fun () -> expect |> equal 1 1) -let () = test "equal 2" (fun () -> expect |> equal "foo" "foo") +let () = test "equal" (fun () -> expect |> equal (4 - 3) 1) +let () = test "equal 2" (fun () -> expect |> equal ("f" ^ "oo") "foo") +let () = test "ok" (fun () -> expect |> ok (true || false)) module Deep_strict_equal = struct type foo = Foo of int diff --git a/test/components.re b/test/components.re index 4e940be..a01a3aa 100644 --- a/test/components.re +++ b/test/components.re @@ -6,7 +6,7 @@ Domloader.init(); module Hello = { [@react.component] - let make = (~text) =>
{("Hello " ++ text)->React.string}
; + let make = (~text) =>
{"Hello " ++ text |> React.string}
; }; let () = diff --git a/test/dune b/test/dune index f0c985e..99f3072 100644 --- a/test/dune +++ b/test/dune @@ -14,6 +14,7 @@ (rule (alias runtest) (deps + (alias_rec main) (:input ./node/test/bindings.mjs)) (action (run node %{input}))) From cc56e26c55a9376aab4b7fb2f534f7567cffd011 Mon Sep 17 00:00:00 2001 From: Feihong Hsu Date: Mon, 4 Mar 2024 20:41:09 -0600 Subject: [PATCH 2/2] Add source link for raw JS in Domloader --- Makefile | 1 + src/domloader.ml | 1 + 2 files changed, 2 insertions(+) diff --git a/Makefile b/Makefile index d1178d9..a887145 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ DUNE = opam exec -- dune .DEFAULT_GOAL := help +# Make sure build directory is the same in CI even though no local switch is being used DUNE_BUILD_DIR := $(shell pwd)/_build .PHONY: help diff --git a/src/domloader.ml b/src/domloader.ml index 3b771b8..5302bb5 100644 --- a/src/domloader.ml +++ b/src/domloader.ml @@ -3,6 +3,7 @@ let init () = (* this function doesn't do anything, it just allows other modules to load the raw code below *) () +(* Source: https://samthor.au/2022/test-react-builtin/ *) [%%mel.raw {| import * as jsdom from 'jsdom';