Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
rcov/ruby/1.8/gems/rspec-core-2.5.1/lib/rspec/core/metadata.rb | 187 | 151 | 79.14%
|
79.47%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 module RSpec |
2 module Core |
3 class Metadata < Hash |
4 |
5 module LocationKeys |
6 def [](key) |
7 return super if has_key?(key) |
8 case key |
9 when :location |
10 store(:location, location) |
11 when :file_path, :line_number |
12 file_path, line_number = file_and_line_number |
13 store(:file_path, file_path) |
14 store(:line_number, line_number) |
15 self[key] |
16 else |
17 super |
18 end |
19 end |
20 |
21 def location |
22 "#{self[:file_path]}:#{self[:line_number]}" |
23 end |
24 |
25 def file_and_line_number |
26 first_caller_from_outside_rspec =~ /(.+?):(\d+)(|:\d+)/ |
27 return [$1, $2.to_i] |
28 end |
29 |
30 def first_caller_from_outside_rspec |
31 self[:caller].detect {|l| l !~ /\/lib\/rspec\/core/} |
32 end |
33 end |
34 |
35 def initialize(superclass_metadata=nil) |
36 @superclass_metadata = superclass_metadata |
37 if @superclass_metadata |
38 update(@superclass_metadata) |
39 example_group = {:example_group => @superclass_metadata[:example_group]} |
40 else |
41 example_group = {} |
42 end |
43 |
44 store(:example_group, example_group.extend(LocationKeys)) |
45 yield self if block_given? |
46 end |
47 |
48 RESERVED_KEYS = [ |
49 :description, |
50 :example_group, |
51 :execution_result, |
52 :file_path, |
53 :full_description, |
54 :line_number, |
55 :location |
56 ] |
57 |
58 def process(*args) |
59 user_metadata = args.last.is_a?(Hash) ? args.pop : {} |
60 ensure_valid_keys(user_metadata) |
61 |
62 self[:example_group].store(:caller, user_metadata.delete(:caller) || caller) |
63 self[:example_group].store(:describes, described_class_from(*args)) |
64 self[:example_group].store(:description, description_from(*args)) |
65 self[:example_group].store(:full_description, full_description_from(*args)) |
66 self[:example_group].store(:block, user_metadata.delete(:example_group_block)) |
67 |
68 update(user_metadata) |
69 end |
70 |
71 def ensure_valid_keys(user_metadata) |
72 RESERVED_KEYS.each do |key| |
73 if user_metadata.keys.include?(key) |
74 raise <<-EOM |
75 #{"*"*50} |
76 :#{key} is not allowed |
77 |
78 RSpec reserves some hash keys for its own internal use, |
79 including :#{key}, which is used on: |
80 |
81 #{caller(0)[4]}. |
82 |
83 Here are all of RSpec's reserved hash keys: |
84 |
85 #{RESERVED_KEYS.join("\n ")} |
86 #{"*"*50} |
87 EOM |
88 raise ":#{key} is not allowed" |
89 end |
90 end |
91 end |
92 |
93 def for_example(description, user_metadata) |
94 dup.extend(LocationKeys).configure_for_example(description, user_metadata) |
95 end |
96 |
97 def configure_for_example(description, user_metadata) |
98 store(:description, description.to_s) |
99 store(:full_description, "#{self[:example_group][:full_description]} #{self[:description]}") |
100 store(:execution_result, {}) |
101 store(:caller, user_metadata.delete(:caller) || caller) |
102 update(user_metadata) |
103 end |
104 |
105 def apply?(predicate, filters) |
106 filters.send(predicate) do |key, value| |
107 apply_condition(key, value) |
108 end |
109 end |
110 |
111 def relevant_line_numbers(metadata) |
112 line_numbers = [metadata[:line_number]] |
113 if metadata[:example_group] |
114 line_numbers + relevant_line_numbers(metadata[:example_group]) |
115 else |
116 line_numbers |
117 end |
118 end |
119 |
120 def apply_condition(key, value, metadata=self) |
121 case value |
122 when Hash |
123 value.all? { |k, v| apply_condition(k, v, metadata[key]) } |
124 when Regexp |
125 metadata[key] =~ value |
126 when Proc |
127 if value.arity == 2 |
128 # Pass the metadata hash to allow the proc to check if it even has the key. |
129 # This is necessary for the implicit :if exclusion filter: |
130 # { } # => run the example |
131 # { :if => nil } # => exclude the example |
132 # The value of metadata[:if] is the same in these two cases but |
133 # they need to be treated differently. |
134 value.call(metadata[key], metadata) rescue false |
135 else |
136 value.call(metadata[key]) rescue false |
137 end |
138 when Fixnum |
139 if key == :line_number |
140 relevant_line_numbers(metadata).include?(world.preceding_declaration_line(value)) |
141 else |
142 metadata[key] == value |
143 end |
144 else |
145 metadata[key] == value |
146 end |
147 end |
148 |
149 private |
150 |
151 def world |
152 RSpec.world |
153 end |
154 |
155 def superclass_metadata |
156 @superclass_metadata ||= { :example_group => {} } |
157 end |
158 |
159 def description_from(*args) |
160 args.inject("") do |result, a| |
161 a = a.to_s.strip |
162 if result == "" |
163 a |
164 elsif a =~ /^(#|::|\.)/ |
165 "#{result}#{a}" |
166 else |
167 "#{result} #{a}" |
168 end |
169 end |
170 end |
171 |
172 def full_description_from(*args) |
173 if superclass_metadata[:example_group][:full_description] |
174 description_from(superclass_metadata[:example_group][:full_description], *args) |
175 else |
176 description_from(*args) |
177 end |
178 end |
179 |
180 def described_class_from(*args) |
181 superclass_metadata[:example_group][:describes] || begin |
182 args.first unless args.first.is_a?(String) || args.first.is_a?(Symbol) |
183 end |
184 end |
185 end |
186 end |
187 end |
Generated on Fri Apr 22 17:22:42 -0700 2011 with rcov 0.9.8