@@ -1,4 +1,4 @@
|
|||||||
# vibe
|
# tbd
|
||||||
|
|
||||||
A small Clojure HTTP API built on [Ring](https://github.com/ring-clojure/ring) (Jetty) and
|
A small Clojure HTTP API built on [Ring](https://github.com/ring-clojure/ring) (Jetty) and
|
||||||
[reitit](https://github.com/metosin/reitit), with Swagger UI docs, unit tests, dockerized
|
[reitit](https://github.com/metosin/reitit), with Swagger UI docs, unit tests, dockerized
|
||||||
@@ -24,8 +24,8 @@ PORT=8080 clojure -X:run
|
|||||||
Or build and run the container:
|
Or build and run the container:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t vibe .
|
docker build -t tbd .
|
||||||
docker run --rm -p 3000:3000 vibe
|
docker run --rm -p 3000:3000 tbd
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
@@ -80,7 +80,7 @@ collected.
|
|||||||
## Project layout
|
## Project layout
|
||||||
|
|
||||||
```
|
```
|
||||||
src/vibe/
|
src/tbd/
|
||||||
core.clj Router, Ring app, and server startup
|
core.clj Router, Ring app, and server startup
|
||||||
<group>/routes.clj Each route group (health, math, ...) owns its route subtree
|
<group>/routes.clj Each route group (health, math, ...) owns its route subtree
|
||||||
<group>/core.clj Business logic for the group, with no HTTP concerns
|
<group>/core.clj Business logic for the group, with no HTTP concerns
|
||||||
@@ -89,5 +89,5 @@ integration-test/ Dockerized integration tests and coverage harness
|
|||||||
script/ Bash entry points (test, coverage, repl, ...) and coverage helpers
|
script/ Bash entry points (test, coverage, repl, ...) and coverage helpers
|
||||||
```
|
```
|
||||||
|
|
||||||
To add a new group, create `vibe.<group>.routes` with a `routes` fn that returns a reitit route
|
To add a new group, create `tbd.<group>.routes` with a `routes` fn that returns a reitit route
|
||||||
vector, then add it to the router in `src/vibe/core.clj`.
|
vector, then add it to the router in `src/tbd/core.clj`.
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}}
|
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}}
|
||||||
:main-opts ["-m" "cognitect.test-runner"]}
|
:main-opts ["-m" "cognitect.test-runner"]}
|
||||||
;; Line coverage via Cloverage. Only adds the dep + test path; the entry points
|
;; Line coverage via Cloverage. Only adds the dep + test path; the entry points
|
||||||
;; (unit: cloverage.coverage, integration: vibe.integration.coverage) are chosen in script/unit-coverage and script/integration-coverage.
|
;; (unit: cloverage.coverage, integration: tbd.integration.coverage) are chosen in script/unit-coverage and script/integration-coverage.
|
||||||
:cov
|
:cov
|
||||||
{:extra-paths ["test"]
|
{:extra-paths ["test"]
|
||||||
:extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}}}
|
:extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}}}
|
||||||
:run {:exec-fn vibe.core/start-server}}}
|
:run {:exec-fn tbd.core/start-server}}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Integration Tests
|
# Integration Tests
|
||||||
|
|
||||||
Dockerized integration tests for the vibe server.
|
Dockerized integration tests for the tbd server.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ docker-compose up --abort-on-container-exit
|
|||||||
|
|
||||||
## Manual Run (app already running)
|
## Manual Run (app already running)
|
||||||
|
|
||||||
If your vibe app is running locally on port 3000:
|
If your tbd app is running locally on port 3000:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd integration-test
|
cd integration-test
|
||||||
@@ -65,7 +65,7 @@ unit tests, the integration tests, and both combined. From the repo root:
|
|||||||
| Task | What it does | Output |
|
| Task | What it does | Output |
|
||||||
|------|--------------|--------|
|
|------|--------------|--------|
|
||||||
| `script/unit-coverage` | Runs `test/` under Cloverage | `target/coverage/unit/` |
|
| `script/unit-coverage` | Runs `test/` under Cloverage | `target/coverage/unit/` |
|
||||||
| `script/integration-coverage` | Runs the integration suite against a Cloverage-instrumented `vibe-app` container | `target/coverage/integration/` |
|
| `script/integration-coverage` | Runs the integration suite against a Cloverage-instrumented `tbd-app` container | `target/coverage/integration/` |
|
||||||
| `script/coverage-report` | Merges the two `lcov.info` files, prints a per-file table | `target/coverage/merged/` |
|
| `script/coverage-report` | Merges the two `lcov.info` files, prints a per-file table | `target/coverage/merged/` |
|
||||||
| `script/coverage` | All three, in order (the full suite with a joint report) | all of the above |
|
| `script/coverage` | All three, in order (the full suite with a joint report) | all of the above |
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ merged report a line counts as covered if either suite hit it; the HTML shows pe
|
|||||||
counts per suite (`u:` unit, `i:` integration).
|
counts per suite (`u:` unit, `i:` integration).
|
||||||
|
|
||||||
How the integration numbers are collected: `docker-compose.coverage.yml` starts the app via
|
How the integration numbers are collected: `docker-compose.coverage.yml` starts the app via
|
||||||
`vibe.integration.coverage`, which lets Cloverage instrument `src/` and then serves real
|
`tbd.integration.coverage`, which lets Cloverage instrument `src/` and then serves real
|
||||||
traffic until it receives SIGTERM. `script/integration-coverage` stops the container
|
traffic until it receives SIGTERM. `script/integration-coverage` stops the container
|
||||||
(`docker compose stop`) so the report gets written, then copies it out with `docker compose cp`.
|
(`docker compose stop`) so the report gets written, then copies it out with `docker compose cp`.
|
||||||
Plain `script/integration-test` / `script/test` are unchanged and run the uninstrumented app.
|
Plain `script/integration-test` / `script/test` are unchanged and run the uninstrumented app.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Overlay for `script/integration-coverage`: runs vibe-app under Cloverage instead of plainly.
|
# Overlay for `script/integration-coverage`: runs tbd-app under Cloverage instead of plainly.
|
||||||
# Reports land in /app/target/coverage/integration inside the container; script/integration-test copies
|
# Reports land in /app/target/coverage/integration inside the container; script/integration-test copies
|
||||||
# them out after the app is stopped (SIGTERM is what triggers the report).
|
# them out after the app is stopped (SIGTERM is what triggers the report).
|
||||||
services:
|
services:
|
||||||
vibe-app:
|
tbd-app:
|
||||||
build:
|
build:
|
||||||
args:
|
args:
|
||||||
DEPS_ALIASES: run:cov
|
DEPS_ALIASES: run:cov
|
||||||
@@ -10,13 +10,13 @@ services:
|
|||||||
- clojure
|
- clojure
|
||||||
- -M:cov
|
- -M:cov
|
||||||
- -m
|
- -m
|
||||||
- vibe.integration.coverage
|
- tbd.integration.coverage
|
||||||
- --runner
|
- --runner
|
||||||
- integration
|
- integration
|
||||||
- --src-ns-path
|
- --src-ns-path
|
||||||
- src
|
- src
|
||||||
- --extra-test-ns
|
- --extra-test-ns
|
||||||
- vibe.integration.coverage
|
- tbd.integration.coverage
|
||||||
- --lcov
|
- --lcov
|
||||||
- --html
|
- --html
|
||||||
- --output
|
- --output
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
services:
|
services:
|
||||||
vibe-app:
|
tbd-app:
|
||||||
image: vibe-app-integration
|
image: tbd-app-integration
|
||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- "${VIBE_PORT:-3000}:${VIBE_PORT:-3000}"
|
- "${TBD_PORT:-3000}:${TBD_PORT:-3000}"
|
||||||
security_opt:
|
security_opt:
|
||||||
- apparmor:unconfined
|
- apparmor:unconfined
|
||||||
environment:
|
environment:
|
||||||
- PORT=${VIBE_PORT:-3000}
|
- PORT=${TBD_PORT:-3000}
|
||||||
# No container healthcheck: healthchecks run via `docker exec`, which hits the
|
# No container healthcheck: healthchecks run via `docker exec`, which hits the
|
||||||
# same LXC/AppArmor runc bug (opencontainers/runc#5007) as image builds and
|
# same LXC/AppArmor runc bug (opencontainers/runc#5007) as image builds and
|
||||||
# always fails here. integration_test.bb polls the server until it's ready.
|
# always fails here. integration_test.bb polls the server until it's ready.
|
||||||
@@ -17,12 +17,12 @@ services:
|
|||||||
# The suite is baked into the image (Dockerfile) rather than bind-mounted: bind mounts
|
# The suite is baked into the image (Dockerfile) rather than bind-mounted: bind mounts
|
||||||
# resolve on the Docker host, so they break when run from inside a CI job container.
|
# resolve on the Docker host, so they break when run from inside a CI job container.
|
||||||
integration-test:
|
integration-test:
|
||||||
image: vibe-integration-test
|
image: tbd-integration-test
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
security_opt:
|
security_opt:
|
||||||
- apparmor:unconfined
|
- apparmor:unconfined
|
||||||
depends_on:
|
depends_on:
|
||||||
vibe-app:
|
tbd-app:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
entrypoint: ["bb", "/integration_test.bb", "http://vibe-app:${VIBE_PORT:-3000}"]
|
entrypoint: ["bb", "/integration_test.bb", "http://tbd-app:${TBD_PORT:-3000}"]
|
||||||
|
|||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
(ns vibe.integration.coverage
|
(ns tbd.integration.coverage
|
||||||
"Entry point that runs the vibe server under Cloverage instrumentation so the
|
"Entry point that runs the tbd server under Cloverage instrumentation so the
|
||||||
black-box integration tests produce a line-coverage report.
|
black-box integration tests produce a line-coverage report.
|
||||||
|
|
||||||
Cloverage normally instruments the source and then runs a test suite in-process.
|
Cloverage normally instruments the source and then runs a test suite in-process.
|
||||||
Here the 'suite' is the outside world: the runner starts the real server and blocks
|
Here the 'suite' is the outside world: the runner starts the real server and blocks
|
||||||
until the JVM gets SIGTERM (`docker compose stop`), then Cloverage writes its reports.
|
until the JVM gets SIGTERM (`docker compose stop`), then Cloverage writes its reports.
|
||||||
|
|
||||||
Deliberately does not require any vibe.* source namespace at load time: those must
|
Deliberately does not require any tbd.* source namespace at load time: those must
|
||||||
be loaded by Cloverage (instrumented), not by us."
|
be loaded by Cloverage (instrumented), not by us."
|
||||||
(:require [cloverage.coverage :as cov]))
|
(:require [cloverage.coverage :as cov]))
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
(fn [_nses]
|
(fn [_nses]
|
||||||
(let [stop (promise)
|
(let [stop (promise)
|
||||||
main (Thread/currentThread)]
|
main (Thread/currentThread)]
|
||||||
((requiring-resolve 'vibe.core/start-server))
|
((requiring-resolve 'tbd.core/start-server))
|
||||||
;; The report is written by the main thread after the runner returns, but the JVM
|
;; The report is written by the main thread after the runner returns, but the JVM
|
||||||
;; only stays up while shutdown hooks run, so the hook must wait for the main thread.
|
;; only stays up while shutdown hooks run, so the hook must wait for the main thread.
|
||||||
(.addShutdownHook (Runtime/getRuntime)
|
(.addShutdownHook (Runtime/getRuntime)
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
(format "%3d/%-3d %6.1f%%" hit total pct))
|
(format "%3d/%-3d %6.1f%%" hit total pct))
|
||||||
|
|
||||||
(defn read-source [file]
|
(defn read-source [file]
|
||||||
;; Cloverage's SF: paths are usually project-relative already (src/vibe/core.clj); fall
|
;; Cloverage's SF: paths are usually project-relative already (src/tbd/core.clj); fall
|
||||||
;; back to the source roots in case they are classpath-relative.
|
;; back to the source roots in case they are classpath-relative.
|
||||||
(some (fn [dir] (let [f (io/file dir file)] (when (.isFile f) (slurp f))))
|
(some (fn [dir] (let [f (io/file dir file)] (when (.isFile f) (slurp f))))
|
||||||
[nil "src" "test" "integration-test"]))
|
[nil "src" "test" "integration-test"]))
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
(format "<td class=\"%s\">%.1f%% <small>(%d/%d)</small></td>"
|
(format "<td class=\"%s\">%.1f%% <small>(%d/%d)</small></td>"
|
||||||
(pct-class (:pct s)) (:pct s) (:hit s) (:total s))))
|
(pct-class (:pct s)) (:pct s) (:hit s) (:total s))))
|
||||||
files (sort (keys merged))]
|
files (sort (keys merged))]
|
||||||
(str "<!doctype html><meta charset=utf-8><title>vibe line coverage</title>
|
(str "<!doctype html><meta charset=utf-8><title>tbd line coverage</title>
|
||||||
<style>
|
<style>
|
||||||
body{font:14px system-ui;margin:2em;color:#222}table{border-collapse:collapse}
|
body{font:14px system-ui;margin:2em;color:#222}table{border-collapse:collapse}
|
||||||
td,th{padding:4px 12px;border-bottom:1px solid #ddd;text-align:left}
|
td,th{padding:4px 12px;border-bottom:1px solid #ddd;text-align:left}
|
||||||
@@ -61,7 +61,7 @@ pre{margin:0;font:12px ui-monospace,monospace}pre span{display:block;white-space
|
|||||||
.c{background:#e3f6e8}.u{background:#fde3e1}.g{display:inline-block;width:9em;color:#888}
|
.c{background:#e3f6e8}.u{background:#fde3e1}.g{display:inline-block;width:9em;color:#888}
|
||||||
details{margin:1em 0}summary{cursor:pointer;font-weight:600}
|
details{margin:1em 0}summary{cursor:pointer;font-weight:600}
|
||||||
</style>
|
</style>
|
||||||
<h1>vibe line coverage</h1>
|
<h1>tbd line coverage</h1>
|
||||||
<table><tr><th>File</th>"
|
<table><tr><th>File</th>"
|
||||||
(apply str (for [k (keys per-suite)] (str "<th>" (name k) "</th>")))
|
(apply str (for [k (keys per-suite)] (str "<th>" (name k) "</th>")))
|
||||||
"<th>merged</th></tr>"
|
"<th>merged</th></tr>"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ source script/lib/docker.sh
|
|||||||
|
|
||||||
build_unit_image
|
build_unit_image
|
||||||
|
|
||||||
id=$(docker create --security-opt apparmor=unconfined vibe-unit \
|
id=$(docker create --security-opt apparmor=unconfined tbd-unit \
|
||||||
clojure -M:cov -m cloverage.coverage \
|
clojure -M:cov -m cloverage.coverage \
|
||||||
--src-ns-path src --test-ns-path test \
|
--src-ns-path src --test-ns-path test \
|
||||||
--lcov --html --output target/coverage/unit)
|
--lcov --html --output target/coverage/unit)
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ cd "$(dirname "$0")/.."
|
|||||||
source script/lib/docker.sh
|
source script/lib/docker.sh
|
||||||
|
|
||||||
build_unit_image
|
build_unit_image
|
||||||
exec docker run --rm --security-opt apparmor=unconfined vibe-unit clojure -M:test "$@"
|
exec docker run --rm --security-opt apparmor=unconfined tbd-unit clojure -M:test "$@"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ free_port_in_range() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
port=$(free_port_in_range 30000 40000)
|
port=$(free_port_in_range 30000 40000)
|
||||||
echo "[test] starting vibe-app on random port $port${COVERAGE:+ (under coverage instrumentation)}"
|
echo "[test] starting tbd-app on random port $port${COVERAGE:+ (under coverage instrumentation)}"
|
||||||
|
|
||||||
compose=(docker compose)
|
compose=(docker compose)
|
||||||
if [[ -n "${COVERAGE:-}" ]]; then
|
if [[ -n "${COVERAGE:-}" ]]; then
|
||||||
@@ -38,7 +38,7 @@ fi
|
|||||||
use_builder
|
use_builder
|
||||||
|
|
||||||
cd integration-test
|
cd integration-test
|
||||||
export VIBE_PORT=$port
|
export TBD_PORT=$port
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
local status=$?
|
local status=$?
|
||||||
@@ -56,9 +56,9 @@ trap 'exit 143' TERM
|
|||||||
# builds. DEPS_ALIASES must match build.args in docker-compose.coverage.yml.
|
# builds. DEPS_ALIASES must match build.args in docker-compose.coverage.yml.
|
||||||
docker buildx build --load \
|
docker buildx build --load \
|
||||||
--build-arg "DEPS_ALIASES=run${COVERAGE:+:cov}" \
|
--build-arg "DEPS_ALIASES=run${COVERAGE:+:cov}" \
|
||||||
-t vibe-app-integration \
|
-t tbd-app-integration \
|
||||||
-f "$root/Dockerfile" "$root"
|
-f "$root/Dockerfile" "$root"
|
||||||
docker buildx build --load -t vibe-integration-test "$root/integration-test"
|
docker buildx build --load -t tbd-integration-test "$root/integration-test"
|
||||||
|
|
||||||
# `run` returns the test container's own exit code; `up --abort-on-container-exit` can leak
|
# `run` returns the test container's own exit code; `up --abort-on-container-exit` can leak
|
||||||
# the app's SIGTERM exit (143) during teardown instead.
|
# the app's SIGTERM exit (143) during teardown instead.
|
||||||
@@ -69,11 +69,11 @@ if [[ -n "${COVERAGE:-}" ]]; then
|
|||||||
# SIGTERM is what makes Cloverage write its report, so stop (not kill) the app and pull
|
# SIGTERM is what makes Cloverage write its report, so stop (not kill) the app and pull
|
||||||
# the report out of the stopped container before `down` removes it.
|
# the report out of the stopped container before `down` removes it.
|
||||||
out_dir=$root/target/coverage
|
out_dir=$root/target/coverage
|
||||||
echo "[test] stopping vibe-app to flush coverage report"
|
echo "[test] stopping tbd-app to flush coverage report"
|
||||||
"${compose[@]}" stop -t 120 vibe-app || true
|
"${compose[@]}" stop -t 120 tbd-app || true
|
||||||
rm -rf "$out_dir/integration"
|
rm -rf "$out_dir/integration"
|
||||||
mkdir -p "$out_dir"
|
mkdir -p "$out_dir"
|
||||||
if ! "${compose[@]}" cp vibe-app:/app/target/coverage/integration "$out_dir" \
|
if ! "${compose[@]}" cp tbd-app:/app/target/coverage/integration "$out_dir" \
|
||||||
|| [[ ! -f $out_dir/integration/lcov.info ]]; then
|
|| [[ ! -f $out_dir/integration/lcov.info ]]; then
|
||||||
echo "[test] WARNING: no integration coverage report was produced"
|
echo "[test] WARNING: no integration coverage report was produced"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# (opencontainers/runc#5007) that fails RUN steps during image build.
|
# (opencontainers/runc#5007) that fails RUN steps during image build.
|
||||||
|
|
||||||
use_builder() {
|
use_builder() {
|
||||||
local builder=vibe-builder
|
local builder=tbd-builder
|
||||||
if ! docker buildx inspect "$builder" >/dev/null 2>&1; then
|
if ! docker buildx inspect "$builder" >/dev/null 2>&1; then
|
||||||
docker buildx create --name "$builder" \
|
docker buildx create --name "$builder" \
|
||||||
--driver docker-container \
|
--driver docker-container \
|
||||||
@@ -13,8 +13,8 @@ use_builder() {
|
|||||||
docker buildx use "$builder"
|
docker buildx use "$builder"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Builds the app image with the test and coverage deps pre-fetched, tagged vibe-unit.
|
# Builds the app image with the test and coverage deps pre-fetched, tagged tbd-unit.
|
||||||
build_unit_image() {
|
build_unit_image() {
|
||||||
use_builder
|
use_builder
|
||||||
docker buildx build --load --build-arg DEPS_ALIASES=test:cov -t vibe-unit .
|
docker buildx build --load --build-arg DEPS_ALIASES=test:cov -t tbd-unit .
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
(ns vibe.core
|
(ns tbd.core
|
||||||
(:require [ring.adapter.jetty :as jetty]
|
(:require [ring.adapter.jetty :as jetty]
|
||||||
[ring.middleware.defaults :refer [wrap-defaults api-defaults]]
|
[ring.middleware.defaults :refer [wrap-defaults api-defaults]]
|
||||||
[ring.middleware.head :refer [wrap-head]]
|
[ring.middleware.head :refer [wrap-head]]
|
||||||
@@ -7,22 +7,22 @@
|
|||||||
[reitit.swagger-ui :as swagger-ui]
|
[reitit.swagger-ui :as swagger-ui]
|
||||||
[reitit.ring.middleware.muuntaja :as muuntaja-middleware]
|
[reitit.ring.middleware.muuntaja :as muuntaja-middleware]
|
||||||
[muuntaja.core :as m]
|
[muuntaja.core :as m]
|
||||||
[vibe.health.routes :as health]
|
[tbd.health.routes :as health]
|
||||||
[vibe.math.routes :as math]))
|
[tbd.math.routes :as math]))
|
||||||
|
|
||||||
;; Each logical group (health, users, orders, ...) owns a `vibe.<group>.routes`
|
;; Each logical group (health, users, orders, ...) owns a `tbd.<group>.routes`
|
||||||
;; namespace that returns its own route subtree; they're concatenated here.
|
;; namespace that returns its own route subtree; they're concatenated here.
|
||||||
(def router
|
(def router
|
||||||
(ring/router
|
(ring/router
|
||||||
[["/swagger.json"
|
[["/swagger.json"
|
||||||
{:get {:no-doc true
|
{:get {:no-doc true
|
||||||
:swagger {:info {:title "vibe API" :version "1.0.0"}}
|
:swagger {:info {:title "tbd API" :version "1.0.0"}}
|
||||||
:handler (swagger/create-swagger-handler)}}]
|
:handler (swagger/create-swagger-handler)}}]
|
||||||
["/" {:get {:no-doc true
|
["/" {:get {:no-doc true
|
||||||
:handler (fn [_req]
|
:handler (fn [_req]
|
||||||
{:status 200
|
{:status 200
|
||||||
:headers {"Content-Type" "text/plain; charset=utf-8"}
|
:headers {"Content-Type" "text/plain; charset=utf-8"}
|
||||||
:body "vibe API — see /api-docs for documentation, /swagger.json for the spec"})}}]
|
:body "tbd API — see /api-docs for documentation, /swagger.json for the spec"})}}]
|
||||||
(health/routes)
|
(health/routes)
|
||||||
(math/routes)]
|
(math/routes)]
|
||||||
{:data {:muuntaja m/instance
|
{:data {:muuntaja m/instance
|
||||||
@@ -44,15 +44,15 @@
|
|||||||
(defn start-server [& [_ opts]]
|
(defn start-server [& [_ opts]]
|
||||||
(let [port (Integer/parseInt (str (or (System/getenv "PORT")
|
(let [port (Integer/parseInt (str (or (System/getenv "PORT")
|
||||||
(get opts :port 3000))))]
|
(get opts :port 3000))))]
|
||||||
(println (format "[vibe] starting server on port %d..." port))
|
(println (format "[tbd] starting server on port %d..." port))
|
||||||
(try
|
(try
|
||||||
(let [server (jetty/run-jetty (wrap-defaults app api-defaults)
|
(let [server (jetty/run-jetty (wrap-defaults app api-defaults)
|
||||||
{:port port
|
{:port port
|
||||||
:join? false})]
|
:join? false})]
|
||||||
(println (format "vibe server running on http://localhost:%d" port))
|
(println (format "tbd server running on http://localhost:%d" port))
|
||||||
(add-shutdown-hook server))
|
(add-shutdown-hook server))
|
||||||
(catch Throwable t
|
(catch Throwable t
|
||||||
(println "[vibe] FAILED to start server:" (.getMessage t))
|
(println "[tbd] FAILED to start server:" (.getMessage t))
|
||||||
(.printStackTrace t)
|
(.printStackTrace t)
|
||||||
(throw t)))))
|
(throw t)))))
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
(ns vibe.health.routes)
|
(ns tbd.health.routes)
|
||||||
|
|
||||||
(defn routes []
|
(defn routes []
|
||||||
["/api/ping"
|
["/api/ping"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
(ns vibe.math.core
|
(ns tbd.math.core
|
||||||
"Business logic for the math group. No HTTP concerns in here.")
|
"Business logic for the math group. No HTTP concerns in here.")
|
||||||
|
|
||||||
(defn add [x y]
|
(defn add [x y]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
(ns vibe.math.routes
|
(ns tbd.math.routes
|
||||||
(:require [vibe.math.core :as math]))
|
(:require [tbd.math.core :as math]))
|
||||||
|
|
||||||
(defn- parse-num [s]
|
(defn- parse-num [s]
|
||||||
(when s
|
(when s
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
(ns vibe.math.core-test
|
(ns tbd.math.core-test
|
||||||
(:require [clojure.test :refer [deftest is testing]]
|
(:require [clojure.test :refer [deftest is testing]]
|
||||||
[vibe.math.core :as math]))
|
[tbd.math.core :as math]))
|
||||||
|
|
||||||
(deftest add-test
|
(deftest add-test
|
||||||
(testing "integers"
|
(testing "integers"
|
||||||
Reference in New Issue
Block a user