Skip to content

Commit

Permalink
Try counting via ExpectationTarget
Browse files Browse the repository at this point in the history
  • Loading branch information
bootstraponline committed Nov 9, 2015
1 parent 1f6f8f5 commit 31f9643
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 42 deletions.
21 changes: 2 additions & 19 deletions lib/rspec_expectation_count/expectation_debug.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,22 @@ def expectation_debug
@expectation_debug ||= []
end

attr_accessor :current_expect, :last_expect
attr_accessor :last_spec_line, :current_spec_line
attr_accessor :current_expect

PWD = Dir.pwd

TracePoint.new do |trace|
file_path = trace.path
if file_path.include?(PWD)
line_number = trace.lineno

# track last spec line for deduping expects
if file_path.end_with?('_spec.rb')
::RSpec::Expectations.last_spec_line = ::RSpec::Expectations.current_spec_line
::RSpec::Expectations.current_spec_line = line_number
end

line = IO.readlines(file_path)[line_number - 1]
line = IO.readlines(file_path)[line_number - 1]
if line.match(/expect\s*[\{\(]/) # expect () || expect { }
expect_hash = { file: file_path, line: line.strip, line_number: line_number }
::RSpec::Expectations.last_expect = ::RSpec::Expectations.current_expect
::RSpec::Expectations.current_expect = expect_hash
end
end
end.enable

def update_expectation_count
# if we've previously seen the expect and haven't advanced to the next spec line
# then it's most likely a duplicate execution.
return if (current_expect == last_expect) && (last_spec_line == current_spec_line)
@expectation_count = expectation_count + 1
update_expectation_debug
end

def update_expectation_debug
expectation_debug << current_expect
end
Expand Down
37 changes: 14 additions & 23 deletions lib/rspec_expectation_count/rspec_expectation_count.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@
require 'rspec/matchers'
require 'rspec/expectations/handler'
require 'rspec/core/formatters/base_text_formatter'
require 'rspec/expectations/expectation_target'
# https://github.com/rspec/rspec-core/issues/740

unless ::RSpec::Expectations.respond_to?(:expectation_count)
module RSpec
module Expectations
class ExpectationTarget
alias_method :old_initialize, :initialize

def initialize(*args)
old_initialize(*args)
::RSpec::Expectations.update_expectation_count
end
end

class << self
def expectation_count
@expectation_count ||= 0
Expand All @@ -19,39 +29,20 @@ def update_expectation_count

def expectation_debug
end
end
end # class << self

# with waiting rspec matchers, it's not sufficient to just count
# the amount of times an expectation is handled. instead we need to
# dedupe and count each expectation exactly once (exluding retries)
#
# this logic relies on trace points so it's handled in the optional
# expectation_debug.rb file
class PositiveExpectationHandler
class << self
alias_method :old_handle_matcher, :handle_matcher

def handle_matcher(*args)
::RSpec::Expectations.update_expectation_count
old_handle_matcher(*args)
end
end
end

class NegativeExpectationHandler
class << self
alias_method :old_handle_matcher, :handle_matcher

def handle_matcher(*args)
::RSpec::Expectations.update_expectation_count
old_handle_matcher(*args)
end
end
end
# class PositiveExpectationHandler
# class NegativeExpectationHandler
end
end

# Print expectation count by default via base text formatter dump_summary
# Print expectation count by default via base text formatter dump_summary
module RSpec
module Core
module Formatters
Expand Down
5 changes: 5 additions & 0 deletions spec/rspec_expectation_count_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@
output = `rspec spec3/dupe_spec.rb`
expect(output).to match '5 expectations'
end

it 'dedupes expects correctly' do
output = `rspec spec3/dupe2_spec.rb`
expect(output).to match '1 expectations'
end
end
5 changes: 5 additions & 0 deletions spec3/assert.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
def assert_true
expect(1).to eq(1)
end

def assert_test
@count = 0
expect { @count += 1 }.to become_eq 3
end
13 changes: 13 additions & 0 deletions spec3/dupe2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require_relative '../lib/rspec_expectation_count'
require_relative '../lib/rspec_expectation_count/expectation_debug'
require 'rubygems'
require 'waiting_rspec_matchers'
require_relative 'assert'

RSpec.configure { |c| c.include WaitingRspecMatchers }

describe 'count' do
it 'rejects duplicate specs' do
assert_test
end
end

0 comments on commit 31f9643

Please sign in to comment.