Permalink
Browse files

extracted FileCache

  • Loading branch information...
1 parent 1de7c62 commit f2d9231262545c831e909e12ce4c18e8050d03d2 @jimweirich committed Sep 14, 2012
Showing with 79 additions and 32 deletions.
  1. +13 −0 lib/rspec/given/file_cache.rb
  2. +23 −14 lib/rspec/given/line_cache.rb
  3. +43 −18 spec/lib/rspec/given/line_cache_spec.rb
@@ -0,0 +1,13 @@
+module RSpec
+ module Given
+ class FileCache
+ def initialize
+ @lines = {}
+ end
+
+ def get(file_name)
+ @lines[file_name] ||= open(file_name) { |f| f.readlines }
+ end
+ end
+ end
+end
@@ -1,33 +1,42 @@
+require 'rspec/given/file_cache'
+
module RSpec
module Given
class LineCache
- def initialize
- @lines = {}
+ def initialize(file_cache=nil)
+ @files = file_cache || FileCache.new
end
def line(file_name, line)
- lines = get_lines(file_name)
+ lines = @files.get(file_name)
extract_lines_from(lines, line-1)
end
+ def to_s
+ "<LineCache>"
+ end
+
private
- def extract_lines_from(lines, index)
- result = lines[index]
- if result =~ /\{ *$/
- result =~ /^( *)[^ ]/
- leading_spaces = $1
- indent = leading_spaces.size
+ def extract_lines_from(lines, line_index)
+ result = lines[line_index]
+ if continued?(result)
+ level = indentation_level(result)
begin
- index += 1
- result << lines[index]
- end while lines[index] =~ /^#{leading_spaces} /
+ line_index += 1
+ result << lines[line_index]
+ end while indentation_level(lines[line_index]) > level
end
result
end
- def get_lines(file_name)
- @lines[file_name] ||= open(file_name) { |f| f.readlines }
+ def continued?(string)
+ string =~ /(\{|do) *$/
+ end
+
+ def indentation_level(string)
+ string =~ /^(\s*)\S/
+ $1.size
end
end
end
@@ -4,43 +4,68 @@ 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" }
+ class FauxFileCache
+ def initialize(lines)
+ @lines = lines.split(/\n/).map { |ln| ln + "\n" }
+ end
+ def get(file_name)
+ @lines
+ end
+ end
+
+ Given(:file) { "MIT-LICENSE" }
+ Given(:line) { 2 }
+ Given(:file_cache) { FauxFileCache.new(input) }
+ Given(:cache) { LineCache.new(file_cache) }
When(:result) { cache.line(file, line) }
describe "reading a line" do
+ Given(:input) {
+ " Now is the time\n" +
+ " for all good men\n" +
+ " to come to the aid\n" +
+ " of their fellowmen\n"
+ }
+ Given(:expected_line) { " for all good men\n" }
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([])}
+ Given(:input) { "" }
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"])}
+ Given(:input) {
+ " Then { y } \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"])}
+ context "when the Then is split over several lines with {}" do
+ Given(:input) {
+ "describe 'foobar' do\n" +
+ " Then {\n" +
+ " x\n" +
+ " }\n" +
+ "end\n"
+ }
Then { result.should == " Then {\n x\n }\n" }
end
+ context "when the Then is split over several lines with do/end" do
+ Given(:input) {
+ "describe 'foobar' do\n" +
+ " Then do\n" +
+ " x\n" +
+ " end\n" +
+ "end\n"
+ }
+ Then { result.should == " Then do\n x\n end\n" }
+ end
end
-
end
end

0 comments on commit f2d9231

Please sign in to comment.