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.
Files changed (118) hide show
  1. data/README +645 -0
  2. data/Rakefile +9 -0
  3. data/lib/lookout.rb +34 -0
  4. data/lib/lookout/aphonic.rb +40 -0
  5. data/lib/lookout/benchmark.rb +11 -0
  6. data/lib/lookout/diff.rb +10 -0
  7. data/lib/lookout/diff/algorithms.rb +5 -0
  8. data/lib/lookout/diff/algorithms/difflib.rb +38 -0
  9. data/lib/lookout/diff/algorithms/difflib/position.rb +92 -0
  10. data/lib/lookout/diff/algorithms/difflib/position/to.rb +47 -0
  11. data/lib/lookout/diff/formats.rb +7 -0
  12. data/lib/lookout/diff/formats/hash.rb +53 -0
  13. data/lib/lookout/diff/formats/inline.rb +39 -0
  14. data/lib/lookout/diff/formats/unified.rb +57 -0
  15. data/lib/lookout/diff/group.rb +61 -0
  16. data/lib/lookout/diff/groups.rb +34 -0
  17. data/lib/lookout/diff/match.rb +36 -0
  18. data/lib/lookout/diff/operation.rb +33 -0
  19. data/lib/lookout/diff/operations.rb +36 -0
  20. data/lib/lookout/diff/operations/delete.rb +9 -0
  21. data/lib/lookout/diff/operations/equal.rb +27 -0
  22. data/lib/lookout/diff/operations/insert.rb +9 -0
  23. data/lib/lookout/diff/operations/replace.rb +9 -0
  24. data/lib/lookout/diff/range.rb +91 -0
  25. data/lib/lookout/equality.rb +178 -0
  26. data/lib/lookout/expectation.rb +50 -0
  27. data/lib/lookout/expectations.rb +62 -0
  28. data/lib/lookout/expectations/behavior.rb +20 -0
  29. data/lib/lookout/expectations/state.rb +29 -0
  30. data/lib/lookout/mock.rb +18 -0
  31. data/lib/lookout/mock/method.rb +70 -0
  32. data/lib/lookout/mock/method/arguments.rb +33 -0
  33. data/lib/lookout/mock/method/arguments/any.rb +11 -0
  34. data/lib/lookout/mock/method/arguments/anything.rb +11 -0
  35. data/lib/lookout/mock/method/arguments/list.rb +15 -0
  36. data/lib/lookout/mock/method/arguments/none.rb +11 -0
  37. data/lib/lookout/mock/method/arguments/one.rb +11 -0
  38. data/lib/lookout/mock/method/calls.rb +11 -0
  39. data/lib/lookout/mock/method/calls/class.rb +21 -0
  40. data/lib/lookout/mock/method/calls/exactly.rb +28 -0
  41. data/lib/lookout/mock/method/calls/instance.rb +25 -0
  42. data/lib/lookout/mock/method/calls/lower.rb +22 -0
  43. data/lib/lookout/mock/method/calls/upper.rb +22 -0
  44. data/lib/lookout/mock/methods.rb +12 -0
  45. data/lib/lookout/mock/object.rb +12 -0
  46. data/lib/lookout/object.rb +11 -0
  47. data/lib/lookout/output.rb +21 -0
  48. data/lib/lookout/rake/tasks.rb +36 -0
  49. data/lib/lookout/rake/tasks/gem.rb +49 -0
  50. data/lib/lookout/rake/tasks/tags.rb +16 -0
  51. data/lib/lookout/rake/tasks/test.rb +46 -0
  52. data/lib/lookout/rake/tasks/test/loader.rb +19 -0
  53. data/lib/lookout/recorder.rb +45 -0
  54. data/lib/lookout/recorder/not.rb +11 -0
  55. data/lib/lookout/recorder/tape.rb +21 -0
  56. data/lib/lookout/recorders.rb +6 -0
  57. data/lib/lookout/recorders/reception.rb +47 -0
  58. data/lib/lookout/recorders/state.rb +35 -0
  59. data/lib/lookout/result.rb +23 -0
  60. data/lib/lookout/results.rb +46 -0
  61. data/lib/lookout/results/error.rb +18 -0
  62. data/lib/lookout/results/error/exception.rb +36 -0
  63. data/lib/lookout/results/error/exception/backtrace.rb +41 -0
  64. data/lib/lookout/results/failure.rb +16 -0
  65. data/lib/lookout/results/failures.rb +6 -0
  66. data/lib/lookout/results/failures/behavior.rb +4 -0
  67. data/lib/lookout/results/failures/state.rb +4 -0
  68. data/lib/lookout/results/fulfilled.rb +9 -0
  69. data/lib/lookout/runners.rb +5 -0
  70. data/lib/lookout/runners/console.rb +22 -0
  71. data/lib/lookout/stub.rb +16 -0
  72. data/lib/lookout/stub/method.rb +105 -0
  73. data/lib/lookout/stub/methods.rb +18 -0
  74. data/lib/lookout/stub/object.rb +11 -0
  75. data/lib/lookout/ui.rb +7 -0
  76. data/lib/lookout/ui/console.rb +36 -0
  77. data/lib/lookout/ui/silent.rb +12 -0
  78. data/lib/lookout/version.rb +5 -0
  79. data/lib/lookout/xml.rb +17 -0
  80. data/test/unit/examples.rb +169 -0
  81. data/test/unit/lookout.rb +7 -0
  82. data/test/unit/lookout/diff.rb +4 -0
  83. data/test/unit/lookout/diff/algorithms/difflib.rb +56 -0
  84. data/test/unit/lookout/diff/algorithms/difflib/position.rb +92 -0
  85. data/test/unit/lookout/diff/algorithms/difflib/position/to.rb +12 -0
  86. data/test/unit/lookout/diff/formats/inline.rb +17 -0
  87. data/test/unit/lookout/diff/formats/unified.rb +67 -0
  88. data/test/unit/lookout/diff/group.rb +4 -0
  89. data/test/unit/lookout/diff/groups.rb +102 -0
  90. data/test/unit/lookout/diff/match.rb +5 -0
  91. data/test/unit/lookout/diff/operations.rb +22 -0
  92. data/test/unit/lookout/diff/operations/delete.rb +45 -0
  93. data/test/unit/lookout/diff/operations/equal.rb +45 -0
  94. data/test/unit/lookout/diff/operations/insert.rb +45 -0
  95. data/test/unit/lookout/diff/operations/replace.rb +45 -0
  96. data/test/unit/lookout/diff/range.rb +50 -0
  97. data/test/unit/lookout/equality.rb +113 -0
  98. data/test/unit/lookout/expectation.rb +39 -0
  99. data/test/unit/lookout/expectations.rb +58 -0
  100. data/test/unit/lookout/expectations/behavior.rb +35 -0
  101. data/test/unit/lookout/expectations/state.rb +29 -0
  102. data/test/unit/lookout/mock.rb +4 -0
  103. data/test/unit/lookout/mock/method.rb +143 -0
  104. data/test/unit/lookout/mock/method/arguments.rb +57 -0
  105. data/test/unit/lookout/mock/method/arguments/any.rb +11 -0
  106. data/test/unit/lookout/recorder.rb +11 -0
  107. data/test/unit/lookout/results.rb +30 -0
  108. data/test/unit/lookout/results/error.rb +7 -0
  109. data/test/unit/lookout/results/failures/behavior.rb +7 -0
  110. data/test/unit/lookout/results/failures/state.rb +7 -0
  111. data/test/unit/lookout/results/fulfilled.rb +7 -0
  112. data/test/unit/lookout/runners/console.rb +4 -0
  113. data/test/unit/lookout/stub.rb +4 -0
  114. data/test/unit/lookout/stub/method.rb +48 -0
  115. data/test/unit/lookout/ui/formatters/exception.rb +5 -0
  116. data/test/unit/lookout/ui/formatters/exception/backtrace.rb +11 -0
  117. data/test/unit/lookout/xml.rb +55 -0
  118. metadata +496 -0
@@ -0,0 +1,61 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Group
4
+ include Enumerable
5
+
6
+ def initialize(*operations)
7
+ @operations = operations
8
+ end
9
+
10
+ def empty?
11
+ operations.empty?
12
+ end
13
+
14
+ def <<(operation)
15
+ operations << operation
16
+ self
17
+ end
18
+
19
+ def fold(context)
20
+ operations[-1] = operations[-1] << context
21
+ self
22
+ end
23
+
24
+ def parity?
25
+ operations.size == 1 and operations.first.parity?
26
+ end
27
+
28
+ def each
29
+ operations.each do |operation|
30
+ yield operation
31
+ end
32
+ self
33
+ end
34
+
35
+ def from
36
+ range(:from)
37
+ end
38
+
39
+ def to
40
+ range(:to)
41
+ end
42
+
43
+ def ==(other)
44
+ operations == other.operations
45
+ end
46
+
47
+ def inspect
48
+ '<#%s %p>' % [self.class, operations]
49
+ end
50
+
51
+ protected
52
+
53
+ attr_reader :operations
54
+
55
+ private
56
+
57
+ def range(target)
58
+ operations.first.send(target).
59
+ at(operations.first.send(target).begin..operations.last.send(target).end)
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Groups
4
+ include Enumerable
5
+
6
+ def initialize(operations, context = 3)
7
+ @operations, @context = operations, context
8
+ end
9
+
10
+ def each
11
+ saved = nil
12
+ group = Lookout::Diff::Group.new
13
+ @operations.each do |operation|
14
+ if saved
15
+ yield saved
16
+ saved = nil
17
+ end
18
+ if group.empty?
19
+ operation = operation >> @context
20
+ group << operation
21
+ elsif operation.foldable? @context * 2
22
+ saved = group << (operation << @context)
23
+ group = Lookout::Diff::Group.new(operation >> @context)
24
+ else
25
+ group << operation
26
+ end
27
+ end
28
+ if saved
29
+ yield saved
30
+ elsif not group.empty?
31
+ yield group.fold(@context)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Match
4
+ include Comparable
5
+
6
+ def initialize(from, to)
7
+ @from, @to = from, to
8
+ end
9
+
10
+ def empty?
11
+ from.empty?
12
+ end
13
+
14
+ def size
15
+ from.size
16
+ end
17
+
18
+ def +(other)
19
+ self.class.new(from + other.from, to + other.to)
20
+ end
21
+
22
+ def touches?(other)
23
+ from.end + 1 == other.from.begin and to.end + 1 == other.to.begin
24
+ end
25
+
26
+ def <=>(other)
27
+ [from.begin, from.end, to.begin, to.end] <=>
28
+ [other.from.begin, other.from.end, other.to.begin, other.to.end]
29
+ end
30
+
31
+ def inspect
32
+ '#<%s %p==%p>' % [self.class, from, to]
33
+ end
34
+
35
+ attr_reader :from, :to
36
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Diff::Operation
4
+ def initialize(from, to)
5
+ @from, @to = from, to
6
+ end
7
+
8
+ def foldable?(window)
9
+ false
10
+ end
11
+
12
+ def >>(size)
13
+ self
14
+ end
15
+
16
+ def <<(size)
17
+ self
18
+ end
19
+
20
+ def parity?
21
+ false
22
+ end
23
+
24
+ def ==(other)
25
+ from == other.from and to == other.to
26
+ end
27
+
28
+ def inspect
29
+ '#<%s %p,%p>' % [self.class, from, to]
30
+ end
31
+
32
+ attr_reader :from, :to
33
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Operations
4
+ autoload :Delete, 'lookout/diff/operations/delete'
5
+ autoload :Equal, 'lookout/diff/operations/equal'
6
+ autoload :Insert, 'lookout/diff/operations/insert'
7
+ autoload :Replace, 'lookout/diff/operations/replace'
8
+
9
+ include Enumerable
10
+
11
+ def initialize(matches)
12
+ @matches = matches
13
+ end
14
+
15
+ def each
16
+ from = to = 0
17
+ @matches.each do |match|
18
+ type = typeify(from, to, match)
19
+ yield type.new(match.from.at(from...match.from.begin),
20
+ match.to.at(to...match.to.begin)) unless type == Equal
21
+ yield Equal.new(match.from, match.to) unless match.empty?
22
+ from, to = match.from.end + 1, match.to.end + 1
23
+ end
24
+ self
25
+ end
26
+
27
+ private
28
+
29
+ def typeify(from, to, match)
30
+ if from < match.from.begin and to < match.to.begin then Replace
31
+ elsif from < match.from.begin then Delete
32
+ elsif to < match.to.begin then Insert
33
+ else Equal
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Operations::Delete
4
+ include Lookout::Diff::Operation
5
+
6
+ def apply(object)
7
+ object.delete(self)
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Operations::Equal
4
+ include Lookout::Diff::Operation
5
+
6
+ def foldable?(window)
7
+ from.size > window
8
+ end
9
+
10
+ def >>(size)
11
+ self.class.new(from.begin_at([from.begin, from.end - size + 1].max),
12
+ to.begin_at([to.begin, to.end - size + 1].max))
13
+ end
14
+
15
+ def <<(size)
16
+ self.class.new(from.end_at([from.end, from.begin + size - 1].min),
17
+ to.end_at([to.end, to.begin + size - 1].min))
18
+ end
19
+
20
+ def parity?
21
+ from == to
22
+ end
23
+
24
+ def apply(object)
25
+ object.equal(self)
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Operations::Insert
4
+ include Lookout::Diff::Operation
5
+
6
+ def apply(object)
7
+ object.insert(self)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Operations::Replace
4
+ include Lookout::Diff::Operation
5
+
6
+ def apply(object)
7
+ object.replace(self)
8
+ end
9
+ end
@@ -0,0 +1,91 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Diff::Range
4
+ include Enumerable
5
+
6
+ def initialize(items, range = 0...items.size)
7
+ @items, @range = items, range.exclude_end? ? range.begin..range.end - 1 : range
8
+ end
9
+
10
+ def empty?
11
+ size < 1
12
+ end
13
+
14
+ def size
15
+ range.end - range.begin + 1
16
+ end
17
+
18
+ def begins_before?(other)
19
+ range.begin < other.range.begin
20
+ end
21
+
22
+ def ends_after?(other)
23
+ range.end > other.range.end
24
+ end
25
+
26
+ def begin_after(other)
27
+ self.class.new(items, other.range.end + 1..range.end)
28
+ end
29
+
30
+ def end_before(other)
31
+ self.class.new(items, range.begin...other.range.begin)
32
+ end
33
+
34
+ def at(range)
35
+ self.class.new(items, range)
36
+ end
37
+
38
+ def +(other)
39
+ self.class.new(items, range.begin..other.range.end)
40
+ end
41
+
42
+ def begin_at(index)
43
+ self.class.new(items, index..range.end)
44
+ end
45
+
46
+ def end_at(index)
47
+ self.class.new(items, range.begin..index)
48
+ end
49
+
50
+ def each
51
+ range.each do |index|
52
+ yield items[index]
53
+ end
54
+ self
55
+ end
56
+
57
+ def each_with_index
58
+ range.each do |index|
59
+ yield items[index], index
60
+ end
61
+ self
62
+ end
63
+
64
+ def to_items
65
+ items[range]
66
+ end
67
+
68
+ def [](index)
69
+ items[index]
70
+ end
71
+
72
+ def begin
73
+ range.begin
74
+ end
75
+
76
+ def end
77
+ range.end
78
+ end
79
+
80
+ def ==(other)
81
+ range == other.range and items == other.items
82
+ end
83
+
84
+ def inspect
85
+ '%p[%p]' % [items, range]
86
+ end
87
+
88
+ protected
89
+
90
+ attr_reader :items, :range
91
+ end
@@ -0,0 +1,178 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Equality
4
+ class << self
5
+ def register(equality, *types)
6
+ eq = equality.new
7
+ types.each do |type|
8
+ equalities[type] = eq
9
+ end
10
+ end
11
+
12
+ def equal?(expected, actual)
13
+ self[expected].equal? expected, actual
14
+ end
15
+
16
+ def message(expected, actual)
17
+ self[expected].message expected, actual
18
+ end
19
+
20
+ def diff(expected, actual)
21
+ self[expected].diff expected, actual
22
+ end
23
+
24
+ private
25
+
26
+ def [](expected)
27
+ equalities[expected.class.ancestors.find{ |type| equalities[type] }]
28
+ end
29
+
30
+ def equalities
31
+ @equalities ||= {}
32
+ end
33
+ end
34
+ end
35
+
36
+ class Lookout::Equality::Object
37
+ Lookout::Equality.register self, Object
38
+
39
+ def equal?(expected, actual)
40
+ expected == actual
41
+ end
42
+
43
+ def message(expected, actual)
44
+ format = format(expected, actual)
45
+ return format unless diff = diff(expected, actual)
46
+ (diff.include?("\n") ? "%s\n%s" : '%s: %s') % [format, diff]
47
+ end
48
+
49
+ def diff(expected, actual)
50
+ end
51
+
52
+ private
53
+
54
+ def format(expected, actual)
55
+ '%p≠%p' % [actual, expected]
56
+ end
57
+ end
58
+
59
+ class Lookout::Equality::Includes < Lookout::Equality::Object
60
+ Lookout::Equality.register self, Module, Range, Regexp
61
+
62
+ def equal?(expected, actual)
63
+ expected === actual or expected == actual
64
+ end
65
+ end
66
+
67
+ class Lookout::Equality::Boolean < Lookout::Equality::Object
68
+ Lookout::Equality.register self, TrueClass, FalseClass
69
+
70
+ def equal?(expected, actual)
71
+ expected == !!actual
72
+ end
73
+ end
74
+
75
+ class Lookout::Equality::String < Lookout::Equality::Object
76
+ Lookout::Equality.register self, String
77
+
78
+ def diff(expected, actual)
79
+ return unless String === actual
80
+ (expected.include? "\n" or actual.include? "\n") ?
81
+ Lookout::Diff::Formats::Unified.
82
+ new(Lookout::Diff::Groups.
83
+ new(Lookout::Diff::Operations.
84
+ new(Lookout::Diff::Algorithms::Difflib.
85
+ new(actual.split("\n"),
86
+ expected.split("\n"))))).to_a.join("\n") :
87
+ Lookout::Diff::Formats::Inline.
88
+ new(Lookout::Diff::Operations.
89
+ new(Lookout::Diff::Algorithms::Difflib.new(actual, expected))).to_s
90
+ end
91
+ end
92
+
93
+ class Lookout::Equality::Array < Lookout::Equality::Object
94
+ Lookout::Equality.register self, Array
95
+
96
+ def equal?(expected, actual)
97
+ return false unless Array === actual and expected.size == actual.size
98
+ expected.each_with_index do |v, i|
99
+ return false unless Lookout::Equality.equal? v, actual[i]
100
+ end
101
+ true
102
+ end
103
+
104
+ def diff(expected, actual)
105
+ return if expected.size == 1 or not Array === actual
106
+ Lookout::Diff::Formats::Unified.
107
+ new(Lookout::Diff::Groups.
108
+ new(Lookout::Diff::Operations.
109
+ new(Lookout::Diff::Algorithms::Difflib.
110
+ new(actual, expected)))).to_a.join("\n")
111
+ end
112
+ end
113
+
114
+ class Lookout::Equality::Hash < Lookout::Equality::Object
115
+ Lookout::Equality.register self, Hash
116
+
117
+ def equal?(expected, actual)
118
+ return false unless Hash === actual and expected.size == actual.size
119
+ expected.all?{ |k, v| Lookout::Equality.equal? v, actual[k] }
120
+ end
121
+
122
+ def diff(expected, actual)
123
+ return if expected.size == 1 or not Hash === actual
124
+ Lookout::Diff::Formats::Hash.
125
+ new(Lookout::Diff::Operations.
126
+ new(Lookout::Diff::Algorithms::Difflib.
127
+ new(array(actual), array(expected)))).to_a.join("\n")
128
+ end
129
+
130
+ private
131
+
132
+ def array(hash)
133
+ hash.to_a.sort_by{ |k, v| k }.map{ |k, v| '%p => %p' % [k, v] }
134
+ end
135
+ end
136
+
137
+ class Lookout::Equality::StandardError < Lookout::Equality::Object
138
+ Lookout::Equality.register self, ::StandardError
139
+
140
+ def equal?(expected, actual)
141
+ expected.equal?(actual) or
142
+ ((actual.respond_to? :message rescue false) and
143
+ ((Regexp === expected.message and expected.message === actual.message) or
144
+ expected.message == actual.message))
145
+ end
146
+
147
+ def diff(expected, actual)
148
+ return super unless String === expected.message and
149
+ StandardError === actual and (actual.respond_to? :message rescue false)
150
+ Lookout::Equality.diff(expected.message, actual.message)
151
+ end
152
+
153
+ private
154
+
155
+ def format(expected, actual)
156
+ Regexp === expected.message ?
157
+ '%p≠#<%s: %p>' % [actual, expected.class, expected.message] :
158
+ super
159
+ end
160
+ end
161
+
162
+ class Lookout::Equality::Output < Lookout::Equality::Object
163
+ Lookout::Equality.register self, Lookout::Output
164
+
165
+ def equal?(expected, _actual)
166
+ expected.expected == expected.actual
167
+ end
168
+
169
+ def diff(expected, _actual)
170
+ Lookout::Equality.diff(expected.expected, expected.actual)
171
+ end
172
+
173
+ private
174
+
175
+ def format(expected, _actual)
176
+ '%p≠%p' % [Lookout::Output.new(expected.actual), expected]
177
+ end
178
+ end