philiprehberger-assert 0.3.0 → 0.5.0

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: e39e8f2c580c51b62aee03496bca3941ac2efe839618a379e5a50721e2e2e0f1
4
- data.tar.gz: 1dd5e255316ff40587c86a795a098ca8d40aba63c3e8ba8505458b9a9455e3b2
3
+ metadata.gz: 806a389a510c91f4c13f8b09ed2b4defbeea816d0d6d9d5f3a1a452add6f12de
4
+ data.tar.gz: 915ce84054018103c7c27618f54d99e0e9ecd3f257056a6e60653f54433b55d7
5
5
  SHA512:
6
- metadata.gz: 25bdfe4360a3d1619e7c0aeb7f7235c47b8cdac18c047ed14c6bbb5baad2b36ad546444f8e7a8b2c0eab814f2d6e3a101fbbec5472c4ed78dcdbb12f1f0456d9
7
- data.tar.gz: 02f70ca6912c4ac85b05d19ed44dcb4c53eb9e89c15752933c46fc2197884df3a74f3089c9ee714a596b30e8db7eeb77d23e35dd60008d1a020bb3b199cb7f9a
6
+ metadata.gz: d54316256352d71f704fe3988caf7f228661a1e86977f4acf3e9486bd2c9b57daf2c9bc70e9a23a927d4e7b206f6e814c16dbbb4798d71a103963c8fed229299
7
+ data.tar.gz: 6ee3a9ba4b4a5b78d2d39f72acf310cc2019391521978fd958d6006c76afa234db0efc203387bec98dc6574913daf92f4445db333a34cc570df8913574cf2fe0
data/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-04-29
11
+
12
+ ### Added
13
+ - `Assert.postcondition(condition, message)` for Design by Contract postcondition checks, complementing the existing `precondition`
14
+
15
+ ## [0.4.0] - 2026-04-15
16
+
17
+ ### Added
18
+ - `starts_with(prefix)` matcher for string prefix assertions
19
+ - `ends_with(suffix)` matcher for string suffix assertions
20
+
10
21
  ## [0.3.0] - 2026-04-04
11
22
 
12
23
  ### Added
data/README.md CHANGED
@@ -45,6 +45,13 @@ Philiprehberger::Assert.that(config).includes_key(:host)
45
45
  Philiprehberger::Assert.that(items).not_empty
46
46
  ```
47
47
 
48
+ ### String Prefix and Suffix
49
+
50
+ ```ruby
51
+ Assert.that('hello world').starts_with('hello')
52
+ Assert.that('hello world').ends_with('world')
53
+ ```
54
+
48
55
  ### Range and Membership
49
56
 
50
57
  ```ruby
@@ -85,19 +92,33 @@ end
85
92
  Philiprehberger::Assert.precondition(user.active?, 'user must be active')
86
93
  ```
87
94
 
95
+ ### Postconditions (Design by Contract)
96
+
97
+ ```ruby
98
+ def withdraw(amount)
99
+ Philiprehberger::Assert.precondition(amount.positive?, 'amount must be positive')
100
+ result = perform_withdrawal(amount)
101
+ Philiprehberger::Assert.postcondition(result.balance >= 0, 'balance must not go negative')
102
+ result
103
+ end
104
+ ```
105
+
88
106
  ## API
89
107
 
90
108
  | Method | Description |
91
109
  |--------|-------------|
92
110
  | `Assert.that(value, message = nil)` | Start a chainable assertion |
93
111
  | `Assert.soft { \|a\| ... }` | Collect failures, raise at end |
94
- | `Assert.precondition(condition, message)` | Design by Contract check |
112
+ | `Assert.precondition(condition, message)` | Design by Contract precondition check |
113
+ | `Assert.postcondition(condition, message)` | Design by Contract postcondition check |
95
114
  | `Assertion#is_a(type)` | Assert value is an instance of type |
96
115
  | `Assertion#gte(num)` | Assert value >= num |
97
116
  | `Assertion#lte(num)` | Assert value <= num |
98
117
  | `Assertion#gt(num)` | Assert value > num |
99
118
  | `Assertion#lt(num)` | Assert value < num |
100
119
  | `Assertion#matches(pattern)` | Assert value matches regex pattern |
120
+ | `Assertion#starts_with(prefix)` | Assert string value starts with prefix |
121
+ | `Assertion#ends_with(suffix)` | Assert string value ends with suffix |
101
122
  | `Assertion#not_blank` | Assert value is not nil or blank |
102
123
  | `Assertion#not_empty` | Assert value is not empty |
103
124
  | `Assertion#includes_key(key)` | Assert hash includes key |
@@ -34,6 +34,14 @@ module Philiprehberger
34
34
  check(pattern.match?(@value.to_s), "Expected #{@value.inspect} to match #{pattern.inspect}")
35
35
  end
36
36
 
37
+ def starts_with(prefix)
38
+ check(@value.start_with?(prefix), "expected to start with #{prefix.inspect}")
39
+ end
40
+
41
+ def ends_with(suffix)
42
+ check(@value.end_with?(suffix), "expected to end with #{suffix.inspect}")
43
+ end
44
+
37
45
  def not_blank
38
46
  check(!@value.nil? && !@value.to_s.strip.empty?, 'Expected value to not be blank')
39
47
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module Assert
5
- VERSION = '0.3.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -33,5 +33,14 @@ module Philiprehberger
33
33
  def self.precondition(condition, message)
34
34
  raise AssertionError, message unless condition
35
35
  end
36
+
37
+ # Design by Contract postcondition check.
38
+ #
39
+ # @param condition [Boolean] the condition to verify
40
+ # @param message [String] failure message
41
+ # @raise [AssertionError] if condition is false
42
+ def self.postcondition(condition, message)
43
+ raise AssertionError, message unless condition
44
+ end
36
45
  end
37
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-assert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-05 00:00:00.000000000 Z
11
+ date: 2026-04-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A lightweight runtime assertion library for Ruby with chainable matchers,
14
14
  soft assertions, and Design by Contract preconditions.