Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add RSpec matchers #21

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/amazing_activist/rspec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

require_relative "./rspec/matchers"
30 changes: 30 additions & 0 deletions lib/amazing_activist/rspec/matchers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

require_relative "./matchers/be_a_failure"
require_relative "./matchers/be_a_success"

module AmazingActivist
module RSpec
module Matchers
UNDEFINED = Object.new.freeze

# @example With any code and any originator
# expect(outcome).to be_a_failure
#
# @example With specific code
# expect(outcome).to be_a_failure(:bad)
def be_a_failure(...)
BeAFailure.new(...)
end

# @example With any value
# expect(outcome).to be_a_success
#
# @example With value
# expect(outcome).to be_a_success(42)
def be_a_success(...)
BeASuccess.new(...)
end
end
end
end
51 changes: 51 additions & 0 deletions lib/amazing_activist/rspec/matchers/be_a_failure.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module AmazingActivist
module RSpec
module Matchers
class BeAFailure
include ::RSpec::Matchers::Composable

def initialize(code = UNDEFINED)
@actual = nil
@code = code
end

def with_code(code)
@code = code
self
end

def matches?(actual)
@actual = actual

return false unless actual.is_a?(AmazingActivist::Outcome::Failure)
return false unless any_code? || values_match?(@code, actual.code)

true
end

def description
"be an AmazingActivist::Outcome::Failure"
end

def failure_message
message = "expected #{actual_formatted}\nto #{description}"
message << "\nwith code: #{::RSpec::Support::ObjectFormatter.format(@code)}" unless any_code?

message
end

private

def any_code?
@code == UNDEFINED
end

def actual_formatted
::RSpec::Support::ObjectFormatter.format(@actual)
end
end
end
end
end
51 changes: 51 additions & 0 deletions lib/amazing_activist/rspec/matchers/be_a_success.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module AmazingActivist
module RSpec
module Matchers
class BeASuccess
include ::RSpec::Matchers::Composable

def initialize(value = UNDEFINED)
@actual = nil
@value = value
end

def with_value(value)
@value = value
self
end

def matches?(actual)
@actual = actual

return false unless actual.is_a?(AmazingActivist::Outcome::Success)
return false unless any_value? || values_match?(@value, actual.unwrap!)

true
end

def description
"be an AmazingActivist::Outcome::Success"
end

def failure_message
message = "expected #{actual_formatted}\nto #{description}"
message << "\nwith value: #{::RSpec::Support::ObjectFormatter.format(@value)}" unless any_value?

message
end

private

def any_value?
@value == UNDEFINED
end

def actual_formatted
::RSpec::Support::ObjectFormatter.format(@actual)
end
end
end
end
end
Loading