Class: Piggly::Tags::AbstractLoopTag

Inherits:
AbstractTag show all
Defined in:
lib/piggly/tags.rb

Overview

Tracks loops where coverage consists of iterating once, iterating more than once, passing through, and at least one full iteration

Direct Known Subclasses

ConditionalLoopTag, UnconditionalLoopTag

Constant Summary

Constants inherited from AbstractTag

Piggly::Tags::AbstractTag::PATTERN

Instance Attribute Summary collapse

Attributes inherited from AbstractTag

#id

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractTag

#tap

Constructor Details

#initialize(*args) ⇒ AbstractLoopTag

Returns a new instance of AbstractLoopTag.



168
169
170
171
# File 'lib/piggly/tags.rb', line 168

def initialize(*args)
  clear
  super
end

Instance Attribute Details

#countObject (readonly)

Returns the value of attribute count.



166
167
168
# File 'lib/piggly/tags.rb', line 166

def count
  @count
end

#endsObject (readonly)

Returns the value of attribute ends.



166
167
168
# File 'lib/piggly/tags.rb', line 166

def ends
  @ends
end

#onceObject (readonly)

Returns the value of attribute once.



166
167
168
# File 'lib/piggly/tags.rb', line 166

def once
  @once
end

#passObject (readonly)

Returns the value of attribute pass.



166
167
168
# File 'lib/piggly/tags.rb', line 166

def pass
  @pass
end

#twiceObject (readonly)

Returns the value of attribute twice.



166
167
168
# File 'lib/piggly/tags.rb', line 166

def twice
  @twice
end

Class Method Details

.statesObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/piggly/tags.rb', line 150

def self.states
  { # Never terminates normally (so @pass must be false)
    0b0000 => "never evaluated",
    0b0001 => "iterations always terminate early. loop always iterates more than once",
    0b0010 => "iterations always terminate early. loop always iterates only once",
    0b0011 => "iterations always terminate early",
    # Terminates normally (one of @pass, @once, @twice must be true)
    0b1001 => "loop always iterates more than once",
    0b1010 => "loop always iterates only once",
    0b1011 => "loop never passes through",
    0b1100 => "loop always passes through",
    0b1101 => "loop never iterates only once",
    0b1110 => "loop never iterates more than once",
    0b1111 => "full coverage" }
end

Instance Method Details

#==(other) ⇒ Object



215
216
217
218
219
220
221
# File 'lib/piggly/tags.rb', line 215

def ==(other)
  @id    == other.id   and
  @ends  == other.ends and
  @pass  == other.pass and
  @once  == other.once and
  @twice == other.twice
end

#clearObject



207
208
209
210
211
212
213
# File 'lib/piggly/tags.rb', line 207

def clear
  @pass  = false
  @once  = false
  @twice = false
  @ends  = false
  @count = 0
end

#complete?Boolean

Returns:



194
195
196
# File 'lib/piggly/tags.rb', line 194

def complete?
  @pass and @once and @twice and @ends
end

#descriptionObject



198
199
200
# File 'lib/piggly/tags.rb', line 198

def description
  self.class.states.fetch(n = state, "unknown tag state: #{n}")
end

#stateObject

Returns state represented as a 4-bit integer



203
204
205
# File 'lib/piggly/tags.rb', line 203

def state
  [@ends,@pass,@once,@twice].reverse.inject([0,0]){|(k,n), bit| [k + 1, n | (bit ? 1 : 0) << k] }.last
end

#styleObject



177
178
179
# File 'lib/piggly/tags.rb', line 177

def style
  "l#{[@pass, @once, @twice, @ends].map{|b| b ? 1 : 0}}"
end

#to_fObject



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/piggly/tags.rb', line 181

def to_f
  # Value space:
  #    (1,2,X)  - loop iterated at least twice and terminated normally
  #    (1,X)    - loop iterated only once and terminated normally
  #    (0,X)    - loop never iterated and terminated normally (pass-thru)
  #    ()       - loop condition was never executed
  #
  # These combinations are ignored, because coverage will probably not reveal bugs
  #    (1,2)    - loop iterated at least twice but terminated early
  #    (1)      - loop iterated only once but terminated early
  100 * (Util::Enumerable.count([@pass, @once, @twice, @ends]){|x| x } / 4.0)
end

#typeObject



173
174
175
# File 'lib/piggly/tags.rb', line 173

def type
  :loop
end