Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/memory-match.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Memory Match (Rstest checkout)

on:
workflow_dispatch:

permissions:
contents: read

jobs:
showcase:
runs-on: ubuntu-22.04
timeout-minutes: 45
env:
METEOR_CHECKOUT: ${{ github.workspace }}/meteor
DO_NOT_TRACK: "1"
defaults:
run:
working-directory: examples/memory-match
steps:
- uses: actions/checkout@v4
with:
path: examples
- uses: actions/checkout@v4
with:
repository: meteor/meteor
ref: rspack-rstest-integration
path: meteor
- uses: actions/setup-node@v4
with:
node-version: "24"
- name: Prepare checkout packages and generated types
run: npm run setup
- name: Install Chromium and system dependencies
run: ./meteor-checkout npx playwright install --with-deps chromium
- run: npm run test:tooling
- run: npm run typecheck
- run: npm run test:unit
- run: npm run test:component
- run: npm run test:browser
- run: npm run test:integration
- run: npm run test:package
- run: npm run test:e2e
- run: npm run test:parallel:native
- run: npm run test:parallel:meteor
- run: npm run test:coverage
- name: Verify normal development startup
run: |
mkdir -p reports
./meteor-checkout run --port 4100 > reports/development.log 2>&1 &
meteor_pid=$!
trap 'kill "$meteor_pid" 2>/dev/null || true' EXIT
for attempt in $(seq 1 120); do
if curl --fail --silent http://localhost:4100/health | grep -q '"mongo":"ready"'; then
exit 0
fi
if ! kill -0 "$meteor_pid" 2>/dev/null; then
break
fi
sleep 1
done
cat reports/development.log
exit 1
- uses: actions/upload-artifact@v4
if: always()
with:
name: memory-match-reports
path: |
examples/memory-match/coverage/
examples/memory-match/reports/
examples/memory-match/test-results/
if-no-files-found: ignore
retention-days: 7
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Each example doubles as a reference for [community packages](https://docs.meteor
- [Notes Offline](#notes-offline)
- [Simple Blog](#simple-blog)
- [Tic-Tac-Toe](#tic-tac-toe)
- [Memory Match](#memory-match)
- [Parties](#parties)
- [Complex Todos (Svelte)](#complex-todos-svelte)
- [Welcome Meteor Cordova](#welcome-meteor-cordova)
Expand Down Expand Up @@ -67,6 +68,18 @@ Each example doubles as a reference for [community packages](https://docs.meteor
- Last Updated At: Apr/21/2026
- Meteor Version: 3.5.2

### Memory Match
- Repository: [meteor/examples/memory-match](./memory-match)
- Why: A cosmic card game with a live leaderboard showcasing Rstest unit, component, browser, Meteor runtime, local package, and end-to-end tests
- Stack: Meteor, Rspack, React, TypeScript, MongoDB, Rstest, Testing Library, Playwright
- Last Updated At: Sep/30/2026
- Meteor Version: Rstest prerelease

Rstest support is currently prerelease, so the example has a temporary Meteor
source-checkout setup. Its [setup guide](./memory-match/README.md) covers the
current commands, while [Rstest integration details](./memory-match/docs/RSTEST.md)
records the migration once the integration is published.

### Parties
- Repository: [meteor/examples/parties](./parties)
- Demo: https://parties.sandbox.galaxycloud.app/
Expand Down
23 changes: 23 additions & 0 deletions examples.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@
"lastUpdatedAt": "Apr/21/2026",
"meteorVersion": "3.5.2"
},
{
"title": "Memory Match",
"slug": "memory-match",
"demo": null,
"tutorial": null,
"repository": "meteor/examples",
"repositoryUrl": "https://github.com/meteor/examples/tree/main/memory-match",
"isInternal": true,
"internalPath": "memory-match",
"why": "A cosmic card game with a live leaderboard showcasing Rstest unit, component, browser, Meteor runtime, local package, and end-to-end tests",
"stack": [
"Meteor",
"Rspack",
"React",
"TypeScript",
"MongoDB",
"Rstest",
"Testing Library",
"Playwright"
],
"lastUpdatedAt": "Sep/30/2026",
"meteorVersion": "Rstest prerelease"
},
{
"title": "Parties",
"slug": "parties",
Expand Down
19 changes: 19 additions & 0 deletions memory-match/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
node_modules/
meteor-checkout
meteor-checkout.tmp-*
coverage/
reports/
test-results/
playwright-report/
*.log
.DS_Store

# Meteor and Rspack generated output
_build
*/build-assets
*/build-chunks
.rsdoctor
.swc/
_build-*/
**/build-assets-*/
**/build-chunks-*/
2 changes: 2 additions & 0 deletions memory-match/.meteor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
local*/
.id
11 changes: 11 additions & 0 deletions memory-match/.meteor/packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
meteor-base
mongo
ecmascript
typescript
zodern:types
shell-server
static-html
react-meteor-data
rspack
rstest
memory-match-engine
2 changes: 2 additions & 0 deletions memory-match/.meteor/platforms
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
server
browser
1 change: 1 addition & 0 deletions memory-match/.meteor/release
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
none
62 changes: 62 additions & 0 deletions memory-match/.meteor/versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
allow-deny@2.1.0
autoupdate@2.0.1
babel-compiler@7.14.1
babel-runtime@1.5.2
base64@1.0.14
binary-heap@1.0.13
boilerplate-generator@2.1.0
caching-compiler@2.0.1
callback-hook@1.8.0
check@1.5.0
core-runtime@1.0.0
ddp@1.4.2
ddp-client@3.3.0
ddp-common@1.4.5
ddp-server@3.3.0
diff-sequence@1.1.3
dynamic-import@0.7.4
ecmascript@0.18.1
ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.13.0
ecmascript-runtime-server@0.11.1
ejson@1.2.0
es5-shim@4.8.1
facts-base@1.0.2
fetch@0.2.0
geojson-utils@1.0.12
hot-code-push@1.0.5
id-map@1.2.0
inter-process-messaging@0.1.2
logging@1.3.6
memory-match-engine@0.0.1
meteor@2.3.1
meteor-base@1.5.2
minimongo@2.2.0
modern-browsers@0.2.3
modules@0.20.3
modules-runtime@0.13.2
mongo@2.4.0
mongo-decimal@0.2.0
mongo-dev-server@1.1.1
mongo-id@1.0.9
npm-mongo@6.16.1
ordered-dict@1.2.0
promise@1.0.0
random@1.2.2
react-fast-refresh@0.3.0
react-meteor-data@4.0.1
reload@1.3.2
retry@1.1.1
routepolicy@1.1.2
rspack@1.1.0
rstest@0.1.0-beta.0
shell-server@0.7.0
socket-stream-client@0.7.0
static-html@1.5.0
static-html-tools@1.0.0
tools-core@1.1.0
tracker@1.3.4
typescript@5.10.1
webapp@2.2.0
webapp-hashing@1.1.2
zodern:types@1.0.13
7 changes: 7 additions & 0 deletions memory-match/.meteorignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
coverage/
reports/
test-results/
playwright-report/
docs/
scripts/
tests/tooling/
1 change: 1 addition & 0 deletions memory-match/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
install-links=true
128 changes: 128 additions & 0 deletions memory-match/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Memory Match

A real-time Memory Match game built with Meteor, React, and TypeScript. Find
eight cosmic pairs, then watch completed scores appear immediately in the shared
leaderboard. The app also demonstrates Rstest across pure game logic, React
components, real Meteor methods and publications, a local Atmosphere package,
and full-browser E2E tests.

![A completed Memory Match board with the live leaderboard](docs/preview.png)

> **Prerelease setup:** Rstest support is not yet in an official Meteor release.
> Until it is, this example uses a Meteor source checkout on the
> [`rspack-rstest-integration`](https://github.com/meteor/meteor/tree/rspack-rstest-integration)
> branch. `meteor-checkout` is a temporary launcher created by setup; it will be
> removed when the integration is published. After setup, commands do not need
> `METEOR_CHECKOUT` to remain exported.

## Stack

| | |
|---|---|
| Runtime | Meteor prerelease with Rstest integration |
| Frontend | React 19 + TypeScript |
| Database | MongoDB |
| Data | Meteor methods, publications, DDP, Minimongo, and Tracker |
| Tests | Rstest, Testing Library, and Playwright |
| Build | Rspack |

## Features

- Play a sixteen-card memory game with accessible, keyboard-friendly controls
- Reactively share completed scores through Meteor pub/sub
- Test game logic in Node, UI in jsdom and Chromium, and app behavior in a real Meteor runtime
- Run a local Atmosphere package and end-to-end browser tests through the same test runner
- Generate Istanbul coverage across app, package, and E2E test sources

## Running it

Use Node.js 22.12 or newer. No global Meteor installation is needed. Run setup
before `npm install` or `npm ci`. The temporary setup expects sibling Meteor and
examples checkouts:

```text
workspace/
├── meteor/ # rspack-rstest-integration
└── examples/
└── memory-match/
```

From an empty workspace, clone both feature branches as siblings:

```bash
mkdir memory-match-workspace
cd memory-match-workspace
git clone --branch feat/memory-match-rstest https://github.com/meteor/examples.git examples
git clone --branch rspack-rstest-integration https://github.com/meteor/meteor.git meteor
cd examples/memory-match
npm run setup
./meteor-checkout npx playwright install chromium
npm start
```

Visit `http://localhost:3000/`. Open a second browser tab before completing a
game to see its leaderboard entry arrive without a page refresh.

If you already have this examples branch, place the Meteor checkout beside it.
If the Meteor checkout is elsewhere, set `METEOR_CHECKOUT` during setup:

```bash
METEOR_CHECKOUT=/absolute/path/to/meteor npm run setup
```

The setup script validates the required branch, links the checkout's unpublished
packages into this app, installs dependencies, generates Meteor declarations,
and creates `meteor-checkout`. On Linux, use
`./meteor-checkout npx playwright install --with-deps chromium` to install
Chromium system dependencies. Rerun setup after changing the checkout branch or
reinstalling dependencies.

## Test suite

| Command | What it does |
|---|---|
| `npm test` | Native game tests in Node |
| `npm run test:watch` | Watch the native game tests |
| `npm run test:component` | React component tests in jsdom |
| `npm run test:browser` | Browser Mode tests in Chromium |
| `npm run test:integration` | Real Meteor server and client tests |
| `npm run test:package` | Local Atmosphere package tests |
| `npm run test:e2e` | Full app E2E tests with Playwright |
| `npm run test:coverage` | Combined Istanbul coverage report |
| `npm run test:parallel:native` | Native Rstest workers |
| `npm run test:parallel:meteor` | Isolated Meteor runtime workers |
| `npm run typecheck` | TypeScript checks |
| `npm run test:tooling` | Temporary checkout setup and launcher checks |

Run `./meteor-checkout npx playwright install chromium` once before Browser Mode
or E2E tests. Stop `npm start` before running tests that use Meteor; they share
the default ports. Full-app test commands manage their own app and MongoDB.

## How it is structured

```text
imports/
api/ # Collection, methods, and publications
game/ # Game rules, scoring, deterministic shuffle, and unit tests
ui/ # React game and leaderboard components with UI tests
packages/
memory-match-engine/ # Local Atmosphere package and its Rstest tests
tests/
e2e/ # Playwright against the complete Meteor application
tooling/ # Checkout and routing checks
rstest.config.ts # Browser, coverage, and test project configuration
```

The ordinary test sources use `@rstest/core`. Tests that import `meteor/*` run
inside real Meteor hosts; pure tests use Rstest's Node, jsdom, or browser
projects. See [Rstest integration details](docs/RSTEST.md) for how to add tests,
the routing rules, coverage behavior, parallel execution, and the publication
checklist.

For a guided tour, use the [showcase walkthrough](docs/SHOWCASE.md).

## Links

- [Meteor docs](https://docs.meteor.com/) · [Meteor guide](https://guide.meteor.com/)
- [React docs](https://react.dev/)
- [Rstest](https://rstest.rs/) · [Testing Library](https://testing-library.com/) · [Playwright](https://playwright.dev/)
Loading