lookout 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +645 -0
- data/Rakefile +9 -0
- data/lib/lookout.rb +34 -0
- data/lib/lookout/aphonic.rb +40 -0
- data/lib/lookout/benchmark.rb +11 -0
- data/lib/lookout/diff.rb +10 -0
- data/lib/lookout/diff/algorithms.rb +5 -0
- data/lib/lookout/diff/algorithms/difflib.rb +38 -0
- data/lib/lookout/diff/algorithms/difflib/position.rb +92 -0
- data/lib/lookout/diff/algorithms/difflib/position/to.rb +47 -0
- data/lib/lookout/diff/formats.rb +7 -0
- data/lib/lookout/diff/formats/hash.rb +53 -0
- data/lib/lookout/diff/formats/inline.rb +39 -0
- data/lib/lookout/diff/formats/unified.rb +57 -0
- data/lib/lookout/diff/group.rb +61 -0
- data/lib/lookout/diff/groups.rb +34 -0
- data/lib/lookout/diff/match.rb +36 -0
- data/lib/lookout/diff/operation.rb +33 -0
- data/lib/lookout/diff/operations.rb +36 -0
- data/lib/lookout/diff/operations/delete.rb +9 -0
- data/lib/lookout/diff/operations/equal.rb +27 -0
- data/lib/lookout/diff/operations/insert.rb +9 -0
- data/lib/lookout/diff/operations/replace.rb +9 -0
- data/lib/lookout/diff/range.rb +91 -0
- data/lib/lookout/equality.rb +178 -0
- data/lib/lookout/expectation.rb +50 -0
- data/lib/lookout/expectations.rb +62 -0
- data/lib/lookout/expectations/behavior.rb +20 -0
- data/lib/lookout/expectations/state.rb +29 -0
- data/lib/lookout/mock.rb +18 -0
- data/lib/lookout/mock/method.rb +70 -0
- data/lib/lookout/mock/method/arguments.rb +33 -0
- data/lib/lookout/mock/method/arguments/any.rb +11 -0
- data/lib/lookout/mock/method/arguments/anything.rb +11 -0
- data/lib/lookout/mock/method/arguments/list.rb +15 -0
- data/lib/lookout/mock/method/arguments/none.rb +11 -0
- data/lib/lookout/mock/method/arguments/one.rb +11 -0
- data/lib/lookout/mock/method/calls.rb +11 -0
- data/lib/lookout/mock/method/calls/class.rb +21 -0
- data/lib/lookout/mock/method/calls/exactly.rb +28 -0
- data/lib/lookout/mock/method/calls/instance.rb +25 -0
- data/lib/lookout/mock/method/calls/lower.rb +22 -0
- data/lib/lookout/mock/method/calls/upper.rb +22 -0
- data/lib/lookout/mock/methods.rb +12 -0
- data/lib/lookout/mock/object.rb +12 -0
- data/lib/lookout/object.rb +11 -0
- data/lib/lookout/output.rb +21 -0
- data/lib/lookout/rake/tasks.rb +36 -0
- data/lib/lookout/rake/tasks/gem.rb +49 -0
- data/lib/lookout/rake/tasks/tags.rb +16 -0
- data/lib/lookout/rake/tasks/test.rb +46 -0
- data/lib/lookout/rake/tasks/test/loader.rb +19 -0
- data/lib/lookout/recorder.rb +45 -0
- data/lib/lookout/recorder/not.rb +11 -0
- data/lib/lookout/recorder/tape.rb +21 -0
- data/lib/lookout/recorders.rb +6 -0
- data/lib/lookout/recorders/reception.rb +47 -0
- data/lib/lookout/recorders/state.rb +35 -0
- data/lib/lookout/result.rb +23 -0
- data/lib/lookout/results.rb +46 -0
- data/lib/lookout/results/error.rb +18 -0
- data/lib/lookout/results/error/exception.rb +36 -0
- data/lib/lookout/results/error/exception/backtrace.rb +41 -0
- data/lib/lookout/results/failure.rb +16 -0
- data/lib/lookout/results/failures.rb +6 -0
- data/lib/lookout/results/failures/behavior.rb +4 -0
- data/lib/lookout/results/failures/state.rb +4 -0
- data/lib/lookout/results/fulfilled.rb +9 -0
- data/lib/lookout/runners.rb +5 -0
- data/lib/lookout/runners/console.rb +22 -0
- data/lib/lookout/stub.rb +16 -0
- data/lib/lookout/stub/method.rb +105 -0
- data/lib/lookout/stub/methods.rb +18 -0
- data/lib/lookout/stub/object.rb +11 -0
- data/lib/lookout/ui.rb +7 -0
- data/lib/lookout/ui/console.rb +36 -0
- data/lib/lookout/ui/silent.rb +12 -0
- data/lib/lookout/version.rb +5 -0
- data/lib/lookout/xml.rb +17 -0
- data/test/unit/examples.rb +169 -0
- data/test/unit/lookout.rb +7 -0
- data/test/unit/lookout/diff.rb +4 -0
- data/test/unit/lookout/diff/algorithms/difflib.rb +56 -0
- data/test/unit/lookout/diff/algorithms/difflib/position.rb +92 -0
- data/test/unit/lookout/diff/algorithms/difflib/position/to.rb +12 -0
- data/test/unit/lookout/diff/formats/inline.rb +17 -0
- data/test/unit/lookout/diff/formats/unified.rb +67 -0
- data/test/unit/lookout/diff/group.rb +4 -0
- data/test/unit/lookout/diff/groups.rb +102 -0
- data/test/unit/lookout/diff/match.rb +5 -0
- data/test/unit/lookout/diff/operations.rb +22 -0
- data/test/unit/lookout/diff/operations/delete.rb +45 -0
- data/test/unit/lookout/diff/operations/equal.rb +45 -0
- data/test/unit/lookout/diff/operations/insert.rb +45 -0
- data/test/unit/lookout/diff/operations/replace.rb +45 -0
- data/test/unit/lookout/diff/range.rb +50 -0
- data/test/unit/lookout/equality.rb +113 -0
- data/test/unit/lookout/expectation.rb +39 -0
- data/test/unit/lookout/expectations.rb +58 -0
- data/test/unit/lookout/expectations/behavior.rb +35 -0
- data/test/unit/lookout/expectations/state.rb +29 -0
- data/test/unit/lookout/mock.rb +4 -0
- data/test/unit/lookout/mock/method.rb +143 -0
- data/test/unit/lookout/mock/method/arguments.rb +57 -0
- data/test/unit/lookout/mock/method/arguments/any.rb +11 -0
- data/test/unit/lookout/recorder.rb +11 -0
- data/test/unit/lookout/results.rb +30 -0
- data/test/unit/lookout/results/error.rb +7 -0
- data/test/unit/lookout/results/failures/behavior.rb +7 -0
- data/test/unit/lookout/results/failures/state.rb +7 -0
- data/test/unit/lookout/results/fulfilled.rb +7 -0
- data/test/unit/lookout/runners/console.rb +4 -0
- data/test/unit/lookout/stub.rb +4 -0
- data/test/unit/lookout/stub/method.rb +48 -0
- data/test/unit/lookout/ui/formatters/exception.rb +5 -0
- data/test/unit/lookout/ui/formatters/exception/backtrace.rb +11 -0
- data/test/unit/lookout/xml.rb +55 -0
- metadata +496 -0
data/Rakefile
ADDED
data/lib/lookout.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Lookout
|
4
|
+
autoload :Aphonic, 'lookout/aphonic'
|
5
|
+
autoload :Benchmark, 'lookout/benchmark'
|
6
|
+
autoload :Diff, 'lookout/diff'
|
7
|
+
autoload :Equality, 'lookout/equality'
|
8
|
+
autoload :Expectation, 'lookout/expectation'
|
9
|
+
autoload :Expectations, 'lookout/expectations'
|
10
|
+
autoload :Output, 'lookout/output'
|
11
|
+
autoload :Mock, 'lookout/mock'
|
12
|
+
autoload :Recorder, 'lookout/recorder'
|
13
|
+
autoload :Recorders, 'lookout/recorders'
|
14
|
+
autoload :Result, 'lookout/result'
|
15
|
+
autoload :Results, 'lookout/results'
|
16
|
+
autoload :Runners, 'lookout/runners'
|
17
|
+
autoload :Stub, 'lookout/stub'
|
18
|
+
autoload :UI, 'lookout/ui'
|
19
|
+
autoload :Version, 'lookout/version'
|
20
|
+
autoload :XML, 'lookout/xml'
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def runner(runner = nil)
|
24
|
+
return @runner = runner if runner
|
25
|
+
@runner ||= Lookout::Runners::Console.new.install
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'lookout/object'
|
31
|
+
|
32
|
+
def Expectations(&block)
|
33
|
+
Lookout.runner.expectations_eval(&block)
|
34
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Aphonic
|
4
|
+
Methods = [
|
5
|
+
:__id__, :__send__, :object_id, # Methods that must be defined
|
6
|
+
:extend, :is_a? # Methods that we need
|
7
|
+
]
|
8
|
+
|
9
|
+
def self.silence(name)
|
10
|
+
undef_method name if
|
11
|
+
instance_methods.include?(RUBY_VERSION < '1.9' ? name.to_s : name.to_sym) and
|
12
|
+
not Methods.include? name.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
instance_methods.each do |name|
|
16
|
+
silence name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
[Kernel, Object].each do |object|
|
21
|
+
object.instance_eval{ class << self; self; end }.instance_eval do
|
22
|
+
method_added = method(:method_added)
|
23
|
+
define_method :method_added do |name|
|
24
|
+
result = method_added.call(name)
|
25
|
+
Lookout::Aphonic.silence name if self == object
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Module
|
32
|
+
append_features = instance_method(:append_features)
|
33
|
+
define_method :append_features do |mod|
|
34
|
+
result = append_features.bind(self).call(mod)
|
35
|
+
instance_methods.each do |name|
|
36
|
+
Lookout::Aphonic.silence name
|
37
|
+
end if mod == Object
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
data/lib/lookout/diff.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Lookout::Diff
|
2
|
+
autoload :Algorithms, 'lookout/diff/algorithms'
|
3
|
+
autoload :Formats, 'lookout/diff/formats'
|
4
|
+
autoload :Group, 'lookout/diff/group'
|
5
|
+
autoload :Groups, 'lookout/diff/groups'
|
6
|
+
autoload :Match, 'lookout/diff/match'
|
7
|
+
autoload :Operation, 'lookout/diff/operation'
|
8
|
+
autoload :Operations, 'lookout/diff/operations'
|
9
|
+
autoload :Range, 'lookout/diff/range'
|
10
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Algorithms::Difflib
|
4
|
+
autoload :Position, 'lookout/diff/algorithms/difflib/position'
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(from, to, &is_junk)
|
9
|
+
@from, @to, @is_junk = from, to, is_junk
|
10
|
+
end
|
11
|
+
|
12
|
+
def each
|
13
|
+
current = Lookout::Diff::Match.new(Lookout::Diff::Range.new(@from, 0...0),
|
14
|
+
Lookout::Diff::Range.new(@to, 0...0))
|
15
|
+
stack = [Position.origin(@from, @to, &@is_junk)]
|
16
|
+
until stack.empty?
|
17
|
+
case item = stack.pop
|
18
|
+
when Position
|
19
|
+
match = item.match
|
20
|
+
next if match.empty?
|
21
|
+
stack.push item.begin_after(match) if item.ends_after? match
|
22
|
+
stack.push match
|
23
|
+
stack.push item.end_before(match) if item.begins_before? match
|
24
|
+
when Lookout::Diff::Match
|
25
|
+
if current.touches? item
|
26
|
+
current += item
|
27
|
+
else
|
28
|
+
yield current unless current.empty?
|
29
|
+
current = item
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
yield current unless current.empty?
|
34
|
+
yield Lookout::Diff::Match.new(current.from.at(@from.size...@from.size),
|
35
|
+
current.to.at(@to.size...@to.size))
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Algorithms::Difflib::Position
|
4
|
+
autoload :To, 'lookout/diff/algorithms/difflib/position/to'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def origin(from, to)
|
8
|
+
to = To.new(to)
|
9
|
+
new(Lookout::Diff::Range.new(from),
|
10
|
+
to,
|
11
|
+
block_given? ?
|
12
|
+
to.indexes.reduce({}){ |j, (k, v)| j[k] = yield(k); j } :
|
13
|
+
{})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(from, to, junk)
|
18
|
+
@from, @to, @junk = from, to, junk
|
19
|
+
end
|
20
|
+
|
21
|
+
def match
|
22
|
+
match = leftmost_longest
|
23
|
+
junk.empty? ? match : expand(expand(match, false), true)
|
24
|
+
end
|
25
|
+
|
26
|
+
def begins_before?(match)
|
27
|
+
from.begins_before? match.from and to.begins_before? match.to
|
28
|
+
end
|
29
|
+
|
30
|
+
def ends_after?(match)
|
31
|
+
from.ends_after? match.from and to.ends_after? match.to
|
32
|
+
end
|
33
|
+
|
34
|
+
def begin_after(match)
|
35
|
+
self.class.new(from.begin_after(match.from), to.begin_after(match.to), junk)
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_before(match)
|
39
|
+
self.class.new(from.end_before(match.from), to.end_before(match.to), junk)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(other)
|
43
|
+
from == other.from and to == other.to and junk == other.junk
|
44
|
+
end
|
45
|
+
|
46
|
+
def inspect
|
47
|
+
'#<%s %p,%p>' % [self.class, from, to]
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
attr_reader :from, :to, :junk
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def leftmost_longest
|
57
|
+
match = Lookout::Diff::Match.new(@from.at(0...0), @to.at(0...0))
|
58
|
+
sizes = Hash.new(0)
|
59
|
+
@from.each_with_index do |item, from|
|
60
|
+
_sizes = Hash.new(0)
|
61
|
+
@to.each_index(item) do |to|
|
62
|
+
size = _sizes[to] = sizes[to - 1] + 1
|
63
|
+
match = Lookout::Diff::Match.
|
64
|
+
new(@from.at(from - size + 1..from),
|
65
|
+
@to.at(to - size + 1..to)) if size > match.size
|
66
|
+
end unless junk[item]
|
67
|
+
sizes = _sizes
|
68
|
+
end
|
69
|
+
match
|
70
|
+
end
|
71
|
+
|
72
|
+
def expand(match, junking)
|
73
|
+
from_begin, to_begin = match.from.begin, match.to.begin
|
74
|
+
while from_begin > @from.begin and to_begin > @to.begin and
|
75
|
+
junk[@to[to_begin - 1]] ^ !junking and
|
76
|
+
@from[from_begin - 1] == @to[to_begin - 1]
|
77
|
+
from_begin -= 1
|
78
|
+
to_begin -= 1
|
79
|
+
end
|
80
|
+
|
81
|
+
from_end, to_end = match.from.end, match.to.end
|
82
|
+
while from_end + 1 <= @from.end and to_end + 1 <= @to.end and
|
83
|
+
junk[@to[to_end + 1]] ^ !junking and
|
84
|
+
@from[from_end + 1] == @to[to_end + 1]
|
85
|
+
from_end += 1
|
86
|
+
to_end += 1
|
87
|
+
end
|
88
|
+
|
89
|
+
Lookout::Diff::Match.new(from.at(from_begin..from_end),
|
90
|
+
to.at(to_begin..to_end))
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Algorithms::Difflib::Position::To <
|
4
|
+
Lookout::Diff::Range
|
5
|
+
def initialize(items, range = 0...items.size, indexes = nil)
|
6
|
+
super items, range
|
7
|
+
@indexes = indexes
|
8
|
+
end
|
9
|
+
|
10
|
+
def each_index(item)
|
11
|
+
indexes[item].each do |index|
|
12
|
+
next if index < range.begin
|
13
|
+
break if index > range.end
|
14
|
+
yield index
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def indexes
|
19
|
+
return @indexes if @indexes
|
20
|
+
@indexes = Hash.new{ |h, k| h[k] = [] }
|
21
|
+
each = items.is_a?(String) ?
|
22
|
+
(' '[0].is_a?(Integer) ? :each_byte : :each_char) :
|
23
|
+
:each
|
24
|
+
i = 0
|
25
|
+
items.send(each) do |item|
|
26
|
+
@indexes[item] << i
|
27
|
+
i += 1
|
28
|
+
end
|
29
|
+
@indexes
|
30
|
+
end
|
31
|
+
|
32
|
+
def begin_after(other)
|
33
|
+
self.class.new(items, other.range.end + 1..range.end, indexes)
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_before(other)
|
37
|
+
self.class.new(items, range.begin...other.range.begin, indexes)
|
38
|
+
end
|
39
|
+
|
40
|
+
def at(range)
|
41
|
+
Lookout::Diff::Range.new(items, range)
|
42
|
+
end
|
43
|
+
|
44
|
+
def ==(other)
|
45
|
+
super and indexes == other.indexes
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Formats::Hash
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(operations)
|
7
|
+
@operations = operations
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@operations.each do |op|
|
12
|
+
operation = Operation.new(op)
|
13
|
+
yield operation.to_s unless operation.empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
class Operation
|
20
|
+
def initialize(operation)
|
21
|
+
@lines = operation.apply(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def empty?
|
25
|
+
@lines.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(operation)
|
29
|
+
mark('-', operation.from)
|
30
|
+
end
|
31
|
+
|
32
|
+
def equal(operation)
|
33
|
+
end
|
34
|
+
|
35
|
+
def insert(operation)
|
36
|
+
mark('+', operation.to)
|
37
|
+
end
|
38
|
+
|
39
|
+
def replace(operation)
|
40
|
+
delete(operation) + insert(operation)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
@lines.join("\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def mark(mark, range)
|
50
|
+
range.map{ |item| '%s%s' % [mark, item] }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Formats::Inline
|
4
|
+
def initialize(operations)
|
5
|
+
@to_s = ToS.new(operations).to_s
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
class ToS
|
15
|
+
def initialize(operations)
|
16
|
+
@to_s = operations.map{ |o| o.apply(self) }.join('').freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(operation)
|
20
|
+
'[-%s-]' % operation.from.to_items
|
21
|
+
end
|
22
|
+
|
23
|
+
def equal(operation)
|
24
|
+
operation.from.to_items
|
25
|
+
end
|
26
|
+
|
27
|
+
def insert(operation)
|
28
|
+
'{+%s+}' % operation.to.to_items
|
29
|
+
end
|
30
|
+
|
31
|
+
def replace(operation)
|
32
|
+
delete(operation) + insert(operation)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
@to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Diff::Formats::Unified
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(groups)
|
7
|
+
@groups = groups
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@groups.each do |group|
|
12
|
+
next if group.parity?
|
13
|
+
yield Group.new(group).to_s
|
14
|
+
end
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
class Group
|
21
|
+
def initialize(group)
|
22
|
+
@group = group
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete(operation)
|
26
|
+
mark('-', operation.from)
|
27
|
+
end
|
28
|
+
|
29
|
+
def equal(operation)
|
30
|
+
mark(' ', operation.from)
|
31
|
+
end
|
32
|
+
|
33
|
+
def insert(operation)
|
34
|
+
mark('+', operation.to)
|
35
|
+
end
|
36
|
+
|
37
|
+
def replace(operation)
|
38
|
+
delete(operation).concat(insert(operation))
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
lines = ['@@ -%d,%d +%d,%d @@' %
|
43
|
+
[@group.from.begin + 1, @group.from.size,
|
44
|
+
@group.to.begin + 1, @group.to.size]]
|
45
|
+
@group.each do |operation|
|
46
|
+
lines.concat operation.apply(self)
|
47
|
+
end
|
48
|
+
lines.join("\n")
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def mark(mark, range)
|
54
|
+
range.map{ |item| '%s%s' % [mark, item] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|