A Ruby testing library that brings precision to your expectations using RFC 2119 compliance levels. 🚥
require "spectus"
require "matchi"
# Define a must-have requirement
test = Spectus.must Matchi::Eq.new(42)
test.call { 42 } # => Pass ✅
# Define an optional feature
test = Spectus.may Matchi::Be.new(:empty?)
test.call { [].empty? } # => Pass ✅
Add to your Gemfile:
gem "spectus"
gem "matchi" # For matchers
Or install directly:
gem install spectus
gem install matchi
Spectus implements RFC 2119 requirement levels to bring clarity and precision to test expectations:
- MUST (✅): Absolute requirement, no exceptions
- SHOULD (
⚠️ ): Strong recommendation with valid exceptions - MAY (💡): Optional feature
This approach helps you clearly communicate the importance of each test in your suite.
Level | Description | Pass Conditions |
---|---|---|
MUST | Absolute requirement | Only when exact match |
SHOULD | Recommended behavior | When matches or has valid reason not to |
MAY | Optional feature | When matches or not implemented |
-
Pass Results:
- ✅ Success (MUST level met)
⚠️ Warning (SHOULD level met)- 💡 Info (MAY level met)
-
Fail Results:
- ❌ Failure (requirement not met)
- 💥 Error (unexpected exception)
test = Spectus.must Matchi::Be.new(1)
test.call { "🦇".size } # Must be exactly 1
test = Spectus.should Matchi::Be.new(0.3)
test.call { 0.1 + 0.2 } # Should be close to 0.3
test = Spectus.may Matchi::Be.new(true)
test.call { [].blank? } # May implement blank? method
Click to expand custom matcher example
class PositiveNumber
def match?
yield.positive?
end
end
test = Spectus.must PositiveNumber.new
test.call { 42 } # => Pass
Click to expand integration example
require "spectus"
require "matchi"
RSpec.describe Calculator do
it "must perform exact arithmetic" do
test = Spectus.must Matchi::Eq.new(4)
expect { test.call { 2 + 2 } }.not_to raise_error
end
end
- Matchi - Collection of compatible matchers
- Test Tube - Underlying test execution engine
- Expresenter - Test result presentation
Released under the MIT License.
- Issues: GitHub Issues
- Documentation: RubyDoc
- Blog Post: Fix Article
This project is sponsored by Sashité