verity 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +75 -6
  3. data/bin/verity +1 -1
  4. data/lib/verity/version.rb +1 -1
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56eba3ab988df08937ded0d1a64257aef3e6b0377e89c205cb1142555cfe6022
4
- data.tar.gz: 767c78b325581dbb233805be573efcf77a1ef6842d1ecb79c23e1036f0d18dd5
3
+ metadata.gz: a15c5874d4b9d45175c6bab46f6c1e6c0f78d7a2b7f3dcd284072d876a397352
4
+ data.tar.gz: ededfcef6a549ead85cd11da04dde4edb8b449a35e36d45cb454c6824aec3136
5
5
  SHA512:
6
- metadata.gz: 9d1afd58fb7e9eead47231b4c08ef719fcdbba846ed760fbc84238baceaca870c76bb160e678f1a3ff81c3ed40ed4fcc2460f7709bbe7fda911008b1704f26b3
7
- data.tar.gz: 99325207bf1dbf549b2ee760d5e2528f8b2ae23e98930c3fe67123c18cf577fb3e8b572ef42ebcb8784f4acf13239516e6b45d2e5c9c468d68be5c6c893f4a83
6
+ metadata.gz: 4a0d0c8b8d0ab9d0f58f23afad6d7febcdd152280659477490db2063a208fcf8fdeb2c1527811770c1a688b6a31adc9eb24101cb7dcc38f53b5c09ffb28d0932
7
+ data.tar.gz: 92a4ed02eca7e52548c92203fa697fe326879a6d68c7d2411c776a968b93c2fb585d0e3ed95b54f3d6b5070644ff50a2dfb0862632cd4f6bc2d3bf8a98bb6017
data/README.md CHANGED
@@ -47,7 +47,7 @@ verity -w cpus # one worker per CPU (Etc.nprocessors)
47
47
  verity --workers 2 verity/ # combine with positional args
48
48
  ```
49
49
 
50
- Exit status is **0** if every claimed test passes, **1** otherwise (`exit` in `bin/verity` mirrors that). **2** is used for invalid CLI options or an invalid `--reporter` / `-r` value.
50
+ Exit status is **0** if every claimed test passes, **1** otherwise (`exit` in `bin/verity` mirrors that). **2** is used for invalid CLI options an unknown flag, a bad `--order` value, or a `path:LINE` filter pointing at a missing file — and for an `ArgumentError` raised during the run (e.g. a `:memory:` manifest combined with `--workers > 1`).
51
51
 
52
52
  ```bash
53
53
  verity --reporter dots
@@ -59,7 +59,60 @@ There is no `--version` flag. The current version is available programmatically
59
59
 
60
60
  Built-in names are the same as for `Verity.build_reporter` (case-insensitive): `colored`, `colored_dots`, `documentation`, `doc`, `dots`, `null`, `none`, `silent`. Custom reporters: `path/to/file.rb:ClassName` (class must `include Verity::Reporter`); the file is `load`ed, then `ClassName.new` is called with no arguments.
61
61
 
62
- `ColoredDotsReporter` (the default) prints green **.** / red **F** / yellow **E** when stdout is a TTY. Set `NO_COLOR` in the environment to disable; set `FORCE_COLOR` or `VERITY_FORCE_COLOR` to `"1"`, `"true"`, or `"yes"` (case-insensitive) to force color when not a TTY.
62
+ `ColoredDotsReporter` (the default) prints green **.** / red **F** / yellow **E** / cyan **S** (skip) when stdout is a TTY. Set `NO_COLOR` in the environment to disable; set `FORCE_COLOR` or `VERITY_FORCE_COLOR` to `"1"`, `"true"`, or `"yes"` (case-insensitive) to force color when not a TTY.
63
+
64
+ ## Execution model
65
+
66
+ ### Parallel runs: the manifest as a work queue
67
+
68
+ With `worker_count > 1`, the coordinator process syncs all runnable tests into the SQLite manifest, forks the workers, and each worker pulls one test at a time by atomically claiming a `pending` row (marking it `running`). When the queue is drained the worker exits; the coordinator then reclaims any rows left `running` (a crashed worker), replays every recorded result through the reporter, and emits the parallel summary.
69
+
70
+ ```mermaid
71
+ flowchart TB
72
+ subgraph coord["Coordinator (parent process)"]
73
+ A["Verity.run"] --> B["sync_manifest!<br/>migrate, replace_tests"]
74
+ B --> C["fork N workers"]
75
+ C --> F["wait for all workers"]
76
+ F --> G["reclaim_abandoned_running!"]
77
+ G --> H["replay results,<br/>report skipped tests"]
78
+ H --> I["on_parallel_complete<br/>(counts, problem_rows)"]
79
+ end
80
+
81
+ DB[("SQLite manifest<br/>pending, running, results")]
82
+
83
+ subgraph wk["Each forked worker (run_manifest)"]
84
+ W["claim_next(worker_id)"] --> X{"row claimed?"}
85
+ X -->|yes| R["run test"]
86
+ R --> Rec["record pass / fail / error"]
87
+ Rec --> W
88
+ X -->|"no: queue empty"| Ex["exit"]
89
+ end
90
+
91
+ B --> DB
92
+ C --> wk
93
+ W <--> DB
94
+ Rec --> DB
95
+ G --> DB
96
+ ```
97
+
98
+ When resource resolvers are registered, a worker that finds only tests conflicting with currently-running resources gets `:blocked` from the claim and retries after a short sleep instead of exiting.
99
+
100
+ ### A test's outcome
101
+
102
+ Every executed test resolves to exactly one status. A clean run is `:pass`; a failed assertion (`AssertionError`) is `:fail`; a timeout or any other raised exception is `:error`. Tests tagged `:skip` are never enqueued — they are reported as `:skip` without running.
103
+
104
+ ```mermaid
105
+ stateDiagram-v2
106
+ [*] --> Skipped: tagged :skip (test or enclosing group)
107
+ [*] --> Running: enqueued and claimed
108
+ Running --> Passed: body completes
109
+ Running --> Failed: AssertionError
110
+ Running --> Errored: Timeout or other StandardError
111
+ Skipped --> [*]
112
+ Passed --> [*]
113
+ Failed --> [*]
114
+ Errored --> [*]
115
+ ```
63
116
 
64
117
  ## Configuration
65
118
 
@@ -89,7 +142,7 @@ Implement {Verity::Reporter} and assign it on configuration. `Verity.run` and `R
89
142
 
90
143
  | Class | Purpose |
91
144
  |-------|---------|
92
- | `ColoredDotsReporter` | Default — green/red/yellow dots with ANSI color (TTY-aware) |
145
+ | `ColoredDotsReporter` | Default — green/red/yellow/cyan dots with ANSI color (TTY-aware) |
93
146
  | `DotsReporter` | Plain `.` / `F` / `E` dots, no color |
94
147
  | `DocumentationReporter` | Prints group titles and test descriptions (outline style) |
95
148
  | `NullReporter` | Discards all output (used internally for parallel child workers) |
@@ -106,7 +159,7 @@ class MyReporter
106
159
  end
107
160
 
108
161
  def on_test_complete(result:, worker_id:)
109
- # See Verity::Runner::Result: :test, :status (:pass | :fail | :error), :error
162
+ # See Verity::Runner::Result: :test, :status (:pass | :fail | :error | :skip), :error
110
163
  end
111
164
 
112
165
  def on_run_finish(summary:, worker_id:)
@@ -132,7 +185,7 @@ For a one-off run without changing global config, pass `Verity::Runner.new(repor
132
185
  | Reader | Stores |
133
186
  |--------|--------|
134
187
  | `run_starts` | `[{ total:, worker_id: }, ...]` |
135
- | `test_completes` | `[{ status:, worker_id: }, ...]` |
188
+ | `test_completes` | `[{ status:, error:, worker_id: }, ...]` |
136
189
  | `run_finishes` | `[{ summary:, worker_id: }, ...]` |
137
190
  | `parallel_finishes` | `[{ counts:, problem_rows: }, ...]` |
138
191
 
@@ -173,9 +226,24 @@ The group stack is cleared before each discovery file is loaded so a stray unclo
173
226
  - **`tags: [:skip]`** — The example is **not** enqueued in the manifest and does **not** run. It still appears in **`Verity::Registry.all`**. The summary line includes **`N skipped`** when `N > 0`. String `"skip"` in tags is treated the same (normalized with `to_sym`). A **`group`** may use **`tags: [:skip]`**; that applies to all nested tests (see **Grouping**).
174
227
  - **`tags: [:focus]`** — If **any** non-skipped registered test has **`:focus`** (including via an enclosing **`group`**), **only** tests that have **`:focus`** in their effective tags are runnable (manifest + direct **`Runner#run`**). If every non-skipped test is focused, the filter does nothing (same as “all focused”). **`Skip` wins:** a test with both **`skip`** and **`focus`** is skipped. When focus narrows the suite, the summary ends with **`(focus)`**.
175
228
 
229
+ How the runnable set is computed: each test's **effective tags** are its enclosing group tags (outer first) plus its own. Skip is evaluated **before** focus — which is why skip wins over focus.
230
+
231
+ ```mermaid
232
+ flowchart TD
233
+ A["All registered tests"] --> B["effective_tags =<br/>inherited group tags + own tags"]
234
+ B --> C{"includes :skip?"}
235
+ C -->|yes| S["excluded<br/>(reported as skipped)"]
236
+ C -->|no| D["candidate"]
237
+ D --> E{"any candidate<br/>has :focus?"}
238
+ E -->|yes| Fy["keep only :focus candidates"]
239
+ E -->|no| Fn["keep all candidates"]
240
+ Fy --> RUN["runnable"]
241
+ Fn --> RUN
242
+ ```
243
+
176
244
  ## `Verity::Test` fields
177
245
 
178
- Each registered test is a `Data.define` struct with 11 fields:
246
+ Each registered test is a `Data.define` struct with 12 fields:
179
247
 
180
248
  | Field | Type | Description |
181
249
  |-------|------|-------------|
@@ -190,6 +258,7 @@ Each registered test is a `Data.define` struct with 11 fields:
190
258
  | `fn` | `Proc` | The test body block |
191
259
  | `group_path` | `Array<String>` | Nested `group` titles at registration time (outer first) |
192
260
  | `inherited_group_tags` | `Array<Symbol>` | Tags accumulated from enclosing `group` blocks (outer first) |
261
+ | `group_scopes` | `Array<GroupScope>` | Source locations of enclosing `group` blocks (`GroupScope` = `title`, `file`, `line`; outer first), used by `path:LINE` filtering |
193
262
 
194
263
  ## Repository layout (this project)
195
264
 
data/bin/verity CHANGED
@@ -69,7 +69,7 @@ begin
69
69
  c.location_filters = filters unless filters.empty?
70
70
  end
71
71
  end
72
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
72
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument, ArgumentError => e
73
73
  warn "verity: #{e.message}"
74
74
  exit 2
75
75
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Verity
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tad Thorley