Permalink
Browse files

Improve HTML/Document/Textmate formatted output

* improve -fhtml output
* auto-detect formats that need line caching
* document source_cache_disabled configuration
  • Loading branch information...
1 parent b0d7251 commit bd865afeb29aef1736b1dd7112fd2dfd3b1d7026 @jimweirich committed Sep 13, 2012
View
@@ -1,6 +1,6 @@
# rspec-given
-Covering rspec-given, version 2.0.0.
+Covering rspec-given, version 2.1.0.beta.3.
rspec-given is an RSpec extension to allow Given/When/Then notation in
RSpec specifications. It is a natural extension of the experimental
@@ -62,7 +62,7 @@ describe Stack do
When(:pop_result) { stack.pop }
Then { pop_result.should == :an_item }
- Then { stack.depth.should == 0 }
+ Also { stack.depth.should == 0 }
end
end
@@ -276,12 +276,12 @@ clauses, then choosing to make some of the _Then_ clauses into _And_
clause will speed up the spec. Otherwise it is probably better to
stick with _Then_ clauses.
-#### Then examples:
+#### Then/And examples:
<pre>
- Then { pop_result.should == :top_item }
- And { stack.top.should == :second_item }
- And { stack.depth.should == original_depth - 1 }
+ Then { pop_result.should == :top_item } # Required
+ And { stack.top.should == :second_item } # No Setup rerun
+ And { stack.depth.should == original_depth - 1 } # ... for these
</pre>
### Invariant
@@ -308,6 +308,21 @@ Notes:
represented in the RSpec formatted output (e.g. the '--format html'
option).
+## Configuration
+
+Just require 'rspec/given' in the spec helper of your project and it
+is ready to go.
+
+If the RSpec format option document, html or textmate are chosen,
+RSpec/Given will automatically add addition source code information to
+the examples to produce better looking output. If you don't care about
+the pretty output and wish to disable source code caching
+unconditionally, then add the following line to your spec helper file:
+
+<pre>
+ RSpec::Given.source_caching_disabled = true
+</pre>
+
# Future Directions
I really like the way the Given framework is working out. I feel my
View
@@ -13,6 +13,8 @@ def self.using_old_rspec?
require 'rspec/given/rspec1_given'
else
require 'rspec/given/version'
+ require 'rspec/given/module_methods'
+ require 'rspec/given/line_cache'
require 'rspec/given/extensions'
require 'rspec/given/configure'
require 'rspec/given/failure'
@@ -1,9 +1,12 @@
require 'rspec'
require 'rspec/given/extensions'
require 'rspec/given/have_failed'
+require 'rspec/given/module_methods'
RSpec.configure do |c|
c.extend(RSpec::Given::ClassExtensions)
c.include(RSpec::Given::InstanceExtensions)
c.include(RSpec::Given::HaveFailed)
+
+ RSpec::Given.detect_formatters(c)
end
@@ -1,4 +1,5 @@
require 'rspec/given/failure'
+require 'rspec/given/module_methods'
module RSpec
module Given
@@ -70,6 +71,10 @@ def _rg_context_info
@_rg_contet_info ||= {}
end
+ def _rg_cache
+ @_rg_cache ||= LineCache.new
+ end
+
# Trigger the evaluation of a Given! block by referencing its
# name.
def _rg_trigger_given(name) # :nodoc:
@@ -161,7 +166,13 @@ def Then(&block)
b = block.binding
file = eval "__FILE__", b
line = eval "__LINE__", b
- eval %{specify do _rg_then(&block) end}, binding, file, line
+ description = _rg_cache.line(file, line) unless RSpec::Given.source_caching_disabled
+ if description
+ cmd = "it(description)"
+ else
+ cmd = "specify"
+ end
+ eval %{#{cmd} do _rg_then(&block) end}, binding, file, line
_rg_context_info[:then_defined] = true
end
@@ -0,0 +1,34 @@
+module RSpec
+ module Given
+ class LineCache
+ def initialize
+ @lines = {}
+ end
+
+ def line(file_name, line)
+ lines = get_lines(file_name)
+ extract_lines_from(lines, line-1)
+ end
+
+ private
+
+ def extract_lines_from(lines, index)
+ result = lines[index]
+ if result =~ /\{ *$/
+ result =~ /^( *)[^ ]/
+ leading_spaces = $1
+ indent = leading_spaces.size
+ begin
+ index += 1
+ result << lines[index]
+ end while lines[index] =~ /^#{leading_spaces} /
+ end
+ result
+ end
+
+ def get_lines(file_name)
+ @lines[file_name] ||= open(file_name) { |f| f.readlines }
+ end
+ end
+ end
+end
@@ -0,0 +1,16 @@
+module RSpec
+ module Given
+ def self.source_caching_disabled
+ @_rg_source_caching_disabled
+ end
+
+ def self.source_caching_disabled=(value)
+ @_rg_source_caching_disabled = value
+ end
+
+ def self.detect_formatters(c)
+ format_active = c.formatters.any? { |f| f.class.name !~ /ProgressFormatter/ }
+ RSpec::Given.source_caching_disabled = ! format_active
+ end
+ end
+end
@@ -5,7 +5,7 @@ module Given
VERSION_MINOR = 1,
VERSION_BUILD = 0,
VERSION_BETA = 'beta',
- VERSION_BETANUM = '1'
+ VERSION_BETANUM = '3'
]
VERSION = VERSION_NUMBERS.join(".")
end
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+module RSpec
+ module Given
+
+ describe LineCache do
+ Given(:file) { "MIT-LICENSE" }
+ Given(:line) { 3 }
+ Given(:cache) { LineCache.new }
+
+ Given(:expected_line) { "Permission is hereby granted, free of charge, to any person obtaining\n" }
+
+ When(:result) { cache.line(file, line) }
+
+ describe "reading a line" do
+ Then { result.should == expected_line }
+ end
+
+ describe "when the file is read twice" do
+ Given { flexmock(cache).should_receive(:open).pass_thru }
+
+ When(:second_result) { cache.line(file, line) }
+
+ Then { second_result.should == expected_line }
+ Then { cache.should have_received(:open).once }
+ end
+
+ context "when the line doesn't exist" do
+ Given { flexmock(cache).should_receive(:open).and_return([])}
+ Then { result.should be_nil }
+ end
+
+ context "when the line has leading and trailing white space" do
+ Given { flexmock(cache).should_receive(:open).and_return(["\n", "\n", " Then { x }\n"])}
+ Then { result.should == " Then { x }\n" }
+ end
+
+ context "when the Then is split over several lines" do
+ Given { flexmock(cache).should_receive(:open).and_return(["\n", "\n", " Then {\n", " x\n", " }\n", "\n"])}
+ Then { result.should == " Then {\n x\n }\n" }
+ end
+
+ end
+
+ end
+end

0 comments on commit bd865af

Please sign in to comment.