lib/pork/isolator.rb in pork-2.0.0 vs lib/pork/isolator.rb in pork-2.1.0
- old
+ new
@@ -66,40 +66,80 @@
stat
end
def build_all_tests result={}, path=[]
suite.tests.each_with_index.inject(result) do |
- r, ((type, imp, test, opts), index)|
+ tests, ((type, imp, block, opts), index)|
current = path + [index]
case type
+ when :describe, :would
+ source_location = expand_source_location(block)
+ init_source_store_path(tests, source_location)
+ end
+
+ case type
when :describe
- Isolator[imp].build_all_tests(r, current) do |nested|
- store_path(r, nested, test, opts[:groups])
+ Isolator[imp].build_all_tests(tests, current) do |nested|
+ store_path(tests, nested, source_location, opts[:groups])
end
when :would
yield(current) if block_given?
- store_path(r, current, test, opts[:groups])
+ store_path(tests, current, source_location, opts[:groups])
end
- r
+ tests
end
end
- def store_path tests, path, test, groups
+ def expand_source_location block
+ file, line = block.source_location
+ [File.expand_path(file), line]
+ end
+
+ def init_source_store_path tests, source_location
+ source, line = source_location
+
+ root = tests[:files] ||= {}
+ map = root[source] ||= {}
+
+ # Most of the time, line is always getting larger because we're
+ # scanning from top to bottom, and we really need to make sure
+ # that the map is sorted because whenever we're looking up which
+ # test we want from a particular line, we want to find the closest
+ # block rounding up. See Isolator#by_source
+ # However, it's not always appending from top to bottom, because
+ # we might be adding more tests from Suite#paste, and the original
+ # test could be defined in the same file, on previous lines!
+ # Because of this, we really need to make sure the map is balanced.
+ # If we ever have ordered map in Ruby, we don't have to do this...
+ # See the test for Isolator.all_tests (test/test_isolator.rb)
+ balanced_append(map, line, [])
+ end
+
+ def store_path tests, path, source_location, groups
store_for_groups(tests, path, groups) if groups
- store_for_source(tests, path, *test.source_location)
+ store_for_source(tests, path, source_location)
end
def store_for_groups tests, path, groups
- r = tests[:groups] ||= {}
+ map = tests[:groups] ||= {}
groups.each do |g|
- (r[g.to_s] ||= []) << path
+ (map[g.to_s] ||= []) << path
end
end
- def store_for_source tests, path, file, line
- r = tests[:files] ||= {}
- ((r[File.expand_path(file)] ||= {})[line] ||= []) << path
+ def store_for_source tests, path, source_location
+ source, line = source_location
+
+ tests[:files][source][line] << path
+ end
+
+ def balanced_append map, key, value
+ last_key = map.reverse_each.first.first unless map.empty?
+
+ map[key] ||= []
+
+ map.replace(Hash[map.sort]) if last_key && key < last_key
end
end
end