hegeltest 0.2.0-x86_64-linux → 0.3.0-x86_64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 002b96ea526d4a771046a0cde5d984554bf945d45d2e1f403d99b1662ea4809e
4
- data.tar.gz: 7f58cf4828c9cab85010f4e2e3df1ade6ff7c6092e213007a34421687d2135ac
3
+ metadata.gz: a6d0f9ced2d7fcce11d764297e9e916389c5eb006835598e36ccadd72569c9e9
4
+ data.tar.gz: f9114f0b6e477796823feecd83633604ff1a1709e1f05805152e6baa191c58d7
5
5
  SHA512:
6
- metadata.gz: b4e9384ac83849a11f404908f046cac1ec6144445e36bd6546900fb7d90763194cd600906f07d944ce5d3cf1d1aa3f30942a8b834fea2f1d1daf741b64f56070
7
- data.tar.gz: 6137838f7bfb75a2d5d183aaf02306b99093c37e160c6726823402534123523434f02c658c02a4ea72e102a86eaa198a38868b6caacb2a0e85a7e0e8ff537ece
6
+ metadata.gz: c04ed219d8587f3e0fbccc0d50c45fc2c920258b6f1a5f5672aa13e3af96b3eef2ef35e7ad6a8a2ff6518eaf3803a126957c1af3c69cacaed29d68d83b27a3a9
7
+ data.tar.gz: 8cbbf7d6e04a6c30fbec40df324b8a63ad1e31c3bbb85cc6cc51d8e1bdd1acd97956d423e164278c073cb5a9a58c86528327e8169d8533a6e727607caca88f0f
data/CHANGELOG.md CHANGED
@@ -2,15 +2,69 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.3.0] - 2026-10-14
6
+
7
+ ### Engine: libhegel 0.45.4 (was 0.45.1)
8
+
9
+ The [libhegel 0.45.4 release notes](https://github.com/hegeldev/hegel-rust/releases/tag/libhegel-v0.45.4)
10
+ describe 0.45.4 alone. The
11
+ [engine changelog](https://github.com/hegeldev/hegel-rust/blob/libhegel-v0.45.4/hegel-c/CHANGELOG.md)
12
+ describes each engine release after 0.45.1, up to 0.45.4.
13
+
14
+ Each platform gem carries `libhegel` 0.45.4. The engine only adds to its C
15
+ interface, and these bindings do not use the additions. The engine
16
+ changes these results for a caller:
17
+
18
+ - A run that generates no valid test case now raises `Hegel::Error` with a
19
+ message that starts with `Unsatisfiable`, also when
20
+ `suppress_health_check:` holds `:filter_too_much` or
21
+ `:test_cases_too_large`. Before, such a run passed. A test that rejects
22
+ every case and expects to pass must now draw at least one valid case.
23
+ - `from_regex` records each drawn string as one choice that the pattern
24
+ constrains. A failure shrinks inside the pattern, so
25
+ `from_regex("(?:bbbb|a)", fullmatch: true)` now shrinks to `"a"`, where
26
+ it stopped at `"bbbb"` before. The example database drops a failure that
27
+ an earlier engine saved for a `from_regex` draw, so the first run after
28
+ the update does not replay it.
29
+ - `from_regex` rejects a look-behind of variable width, such as
30
+ `(?<=a*)b`, with `Hegel::Error`, as Python's `re` does.
31
+ - `\w`, `\d`, `\s`, and case-insensitive matching in `from_regex` follow
32
+ Unicode 17.0. Before, they followed Unicode 15.1.
33
+ - A run stops when its test-case budget or its budget of invalid cases is
34
+ spent. Before, it could also stop after ten rejected cases in a row that
35
+ it had seen before.
36
+
37
+ ## [0.2.1] - 2026-10-08
38
+
39
+ ### Engine: libhegel 0.45.1 (was 0.45.0)
40
+
41
+ The [libhegel 0.45.1 release notes](https://github.com/hegeldev/hegel-rust/releases/tag/libhegel-v0.45.1)
42
+ describe the engine changes.
43
+
44
+ Each platform gem carries `libhegel` 0.45.1. A caller has nothing to
45
+ change. The engine now reads a NULL string buffer with length zero as the
46
+ empty string, and it rejects a NULL buffer with a nonzero length. These
47
+ bindings send neither case, so a drawn value does not change:
48
+ `from_regex("", fullmatch: true)` draws `""` on both engines.
49
+
5
50
  ## [0.2.0] - 2026-10-07
6
51
 
52
+ ### Engine: libhegel 0.45.0 (was 0.32.5)
53
+
54
+ The [libhegel 0.45.0 release notes](https://github.com/hegeldev/hegel-rust/releases/tag/libhegel-v0.45.0)
55
+ describe 0.45.0 alone. The
56
+ [engine changelog](https://github.com/hegeldev/hegel-rust/blob/libhegel-v0.45.0/hegel-c/CHANGELOG.md)
57
+ describes each engine release after 0.32.5, up to 0.45.0.
58
+
59
+ Each platform gem carries `libhegel` 0.45.0. The engine changed its C
60
+ interface in several places between the two, and these bindings follow
61
+ each change. The sections below list what that changes for a caller.
62
+
63
+ ### Ruby
64
+
7
65
  The floor is Ruby 3.4. A project on Ruby 3.3 stays on 0.1.1. See
8
66
  [ADR 0017](docs/adr/0017-raise-the-ruby-floor-to-3-4.md).
9
67
 
10
- Each platform gem carries `libhegel` 0.45.0, up from 0.32.5. The engine
11
- changed its C interface in several places between the two, and these
12
- bindings follow each change.
13
-
14
68
  ### Changes a caller has to make
15
69
 
16
70
  `Hegel.test` no longer takes `stateful_step_count:`. Pass `step_count:` to
@@ -120,6 +174,8 @@ The engine is called through the `ffi` gem. Each platform gem carries the
120
174
  matching `libhegel` 0.32.5 build. The platform-independent gem carries none,
121
175
  so a run on it needs `HEGEL_LIBHEGEL_PATH` pointing at a local build.
122
176
 
177
+ [0.3.0]: https://github.com/meganemura/hegel-ruby/releases/tag/v0.3.0
178
+ [0.2.1]: https://github.com/meganemura/hegel-ruby/releases/tag/v0.2.1
123
179
  [0.2.0]: https://github.com/meganemura/hegel-ruby/releases/tag/v0.2.0
124
180
  [0.1.1]: https://github.com/meganemura/hegel-ruby/releases/tag/v0.1.1
125
181
  [0.1.0]: https://github.com/meganemura/hegel-ruby/releases/tag/v0.1.0
data/docs/README.md CHANGED
@@ -30,6 +30,7 @@ An index of the design records for `hegel-ruby`.
30
30
  - [0021: Run a state machine in rounds, with its own step count](adr/0021-run-a-state-machine-in-rounds-with-its-own-step-count.md)
31
31
  - [0022: Keep microsecond times over a nanosecond engine](adr/0022-keep-microsecond-times-over-a-nanosecond-engine.md)
32
32
  - [0023: Leave unset settings to the engine's profile](adr/0023-leave-unset-settings-to-the-engines-profile.md)
33
+ - [0024: Release when a merge changes the gem version](adr/0024-release-when-a-merge-changes-the-gem-version.md)
33
34
 
34
35
  A new decision gets a new record. A changed decision supersedes the old
35
36
  record instead of editing it, so the history stays readable.
@@ -0,0 +1,49 @@
1
+ # 0024: Release when a merge changes the gem version
2
+
3
+ ## Status
4
+
5
+ Accepted. Replaces the tag push that started the Release workflow.
6
+
7
+ ## Context
8
+
9
+ A release took three steps from the maintainer: merge the pull request that
10
+ prepares the version, push the tag `v<version>` on the merged commit, and
11
+ approve the `release` environment. The tag carried no decision of its own.
12
+ The version in `lib/hegel/version.rb` already said what to release, and the
13
+ approval was the real gate.
14
+
15
+ A daily routine now opens a pull request for each new libhegel release, with
16
+ a "Prepare <version>" commit. The maintainer's part should be the decision,
17
+ not the steps around it.
18
+
19
+ GitHub does not start a workflow from a push that a workflow makes with its
20
+ own `GITHUB_TOKEN`. A workflow that pushed the tag after a merge would
21
+ therefore not start a tag-triggered Release workflow.
22
+
23
+ ## Decision
24
+
25
+ The Release workflow starts on a push to `main` that changes
26
+ `lib/hegel/version.rb`. Its first job reads the version and looks for the tag
27
+ `v<version>`. When the tag exists, as after a revert to a released version,
28
+ the run stops there. Otherwise the publish job waits for the `release`
29
+ environment approval, then builds and pushes the gems from the merged
30
+ commit. The last job creates the tag on that commit and the GitHub release
31
+ together, with `gh release create --target`.
32
+
33
+ The tag is created last, after the gems are out. A rejected approval then
34
+ leaves no tag behind, and rerunning the workflow run releases the same
35
+ commit later.
36
+
37
+ Two alternatives were refused. A workflow that only pushed the tag needs a
38
+ personal access token or a GitHub App token to start the tag-triggered
39
+ workflow, which is a long-lived secret for one step. Creating the tag before
40
+ the approval leaves a tag for a version that may never ship, and the check
41
+ job would then skip that version for good.
42
+
43
+ ## Consequences
44
+
45
+ A release is one merge and one approval. Merge a pull request that changes
46
+ the gem version only when that version should ship.
47
+
48
+ A tag pushed by hand no longer starts a release. The workflow's own run on
49
+ `main` is the place to retry one.
@@ -5,5 +5,5 @@ module Hegel
5
5
  # Hegel::VERSION (the gem's own release): hegel-go and hegel-typescript keep
6
6
  # the two separate too, so bumping the pinned engine can land as its own
7
7
  # commit without also releasing a new gem version.
8
- LIBHEGEL_VERSION = "0.45.0"
8
+ LIBHEGEL_VERSION = "0.45.4"
9
9
  end
data/lib/hegel/runner.rb CHANGED
@@ -178,9 +178,9 @@ module Hegel
178
178
  # Pulls test cases from +run+ until hegel_next_test_case reports none
179
179
  # left (a nil out-parameter, not an error). Never counts iterations
180
180
  # itself: test_cases bounds generation, not how many times shrinking
181
- # and rejected cases call the body. Measured against libhegel 0.45.0, a
181
+ # and rejected cases call the body. Measured against libhegel 0.45.4, a
182
182
  # run configured for 20 test cases whose body rejected nearly every case
183
- # took 1040 to 1537 iterations. +stats+ does its own, different counting
183
+ # took 475 to 1607 iterations. +stats+ does its own, different counting
184
184
  # -- see GenerationStats above.
185
185
  def drive(impl, ctx, run, stats, captures, &block)
186
186
  loop do
data/lib/hegel/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hegel
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -494,12 +494,12 @@ expose) are not available in this binding; `codec:`, `min_codepoint:`, and
494
494
  `max_codepoint:` are the alphabet controls it exposes today.
495
495
 
496
496
  Other generators cover most character-set jobs. These results were measured
497
- with libhegel 0.45.0:
497
+ with libhegel 0.45.4:
498
498
 
499
499
  | Job | Generator | Measured output |
500
500
  |---|---|---|
501
- | Characters to include | `from_regex("[ぁ-んA-Z0-9]{1,5}", fullmatch: true)` | `"ぁ"`, `"Hわ9ごう"`; 30 draws all matched the pattern |
502
- | Characters to exclude | `from_regex("[^,\\t\\n]{0,6}", fullmatch: true)` | `""`, `"\u008FBՔ\u0014੐C"`; 30 draws contained no comma, tab, or newline |
501
+ | Characters to include | `from_regex("[ぁ-んA-Z0-9]{1,5}", fullmatch: true)` | `"0"`, `"ぢ3"`, `"るJこ"`; 30 draws all matched the pattern |
502
+ | Characters to exclude | `from_regex("[^,\\t\\n]{0,6}", fullmatch: true)` | `""`, `"\u0010ùóR'<"`; 30 draws contained no comma, tab, or newline |
503
503
  | A contiguous block | `text(min_codepoint: 0x300, max_codepoint: 0x36F)` | Every character of 100 draws was in U+0300 through U+036F |
504
504
  | An arbitrary alphabet | `arrays(sampled_from(%w[ß a İ]), max_size: 4).map(&:join)` | 30 draws, each built only from `ß`, `a`, and `İ` |
505
505
 
@@ -1219,11 +1219,18 @@ value already in the shape you need):
1219
1219
 
1220
1220
  ```ruby
1221
1221
  result = Hegel.test(test_cases: 20, suppress_health_check: [:filter_too_much], verbosity: :quiet) do |tc|
1222
- tc.draw(integers.filter { |_n| false })
1222
+ tc.draw(integers(min_value: 0, max_value: 1_000_000).filter(&:zero?))
1223
1223
  end
1224
1224
  result # => nil
1225
1225
  ```
1226
1226
 
1227
+ The suppressed check does not let a run pass with no valid input. A
1228
+ predicate that never holds, such as `integers.filter { |_n| false }`,
1229
+ still raises `Hegel::Error`, with a message that starts with
1230
+ `"Unsatisfiable: unable to satisfy the test's assumptions."` Since libhegel
1231
+ 0.45.2, the engine ends every run that generates no valid test case this
1232
+ way.
1233
+
1227
1234
  ## Gotchas
1228
1235
 
1229
1236
  1. **Float defaults include NaN and infinity when unbounded.** `floats` with
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hegeltest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - meganemura
@@ -69,6 +69,7 @@ files:
69
69
  - docs/adr/0021-run-a-state-machine-in-rounds-with-its-own-step-count.md
70
70
  - docs/adr/0022-keep-microsecond-times-over-a-nanosecond-engine.md
71
71
  - docs/adr/0023-leave-unset-settings-to-the-engines-profile.md
72
+ - docs/adr/0024-release-when-a-merge-changes-the-gem-version.md
72
73
  - docs/architecture.md
73
74
  - lib/hegel.rb
74
75
  - lib/hegel/draw_name.rb