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,23 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Result
4
+ class << self
5
+ def is(is)
6
+ [:error, :failure, :fulfilled].each do |type|
7
+ define_method :"#{type}?" do
8
+ type == is
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ def initialize(file, line)
15
+ @file, @line = file, line
16
+ end
17
+
18
+ attr_reader :file, :line
19
+
20
+ def to_s
21
+ '%s:%d' % [file, line]
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results
4
+ autoload :Error, 'lookout/results/error'
5
+ autoload :Failure, 'lookout/results/failure'
6
+ autoload :Failures, 'lookout/results/failures'
7
+ autoload :Fulfilled, 'lookout/results/fulfilled'
8
+
9
+ include Enumerable
10
+
11
+ def initialize
12
+ @results = []
13
+ end
14
+
15
+ def <<(result)
16
+ @results << result
17
+ self
18
+ end
19
+
20
+ def each
21
+ @results.each do |result|
22
+ yield result
23
+ end
24
+ self
25
+ end
26
+
27
+ def succeeded?
28
+ all?{ |result| result.fulfilled? }
29
+ end
30
+
31
+ def size
32
+ @results.size
33
+ end
34
+
35
+ def fulfillments
36
+ select{ |result| result.fulfilled? }
37
+ end
38
+
39
+ def errors
40
+ select{ |result| result.error? }
41
+ end
42
+
43
+ def failures
44
+ select{ |result| result.failure? }
45
+ end
46
+ end
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Error < Lookout::Result
4
+ autoload :Exception, 'lookout/results/error/exception'
5
+
6
+ is :error
7
+
8
+ def initialize(file, line, message, exception)
9
+ super file, line
10
+ @message, @exception = message, Exception.new(exception)
11
+ end
12
+
13
+ attr_reader :message, :exception
14
+
15
+ def to_s
16
+ [super, message, exception].compact.join(': ')
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Error::Exception
4
+ autoload :Backtrace, 'lookout/results/error/exception/backtrace'
5
+
6
+ def initialize(exception)
7
+ @exception = exception
8
+ end
9
+
10
+ def message
11
+ # Chomping off a \n here isn’t 100 percent compatible with how Ruby 1.9
12
+ # does it, but it simplifies the code and also makes the output better if
13
+ # the message is a lone \n.
14
+ message = @exception.message.to_str.chomp("\n")
15
+ if @exception.class == RuntimeError and message.empty?
16
+ 'unhandled exception'
17
+ elsif message.empty?
18
+ @exception.class.name
19
+ elsif @exception.class.name.empty? or @exception.class.name =~ /^#/
20
+ message
21
+ else
22
+ before, newline, after = message.partition("\n")
23
+ '%s (%s)%s%s' % [before, @exception.class.name, newline, after]
24
+ end
25
+ end
26
+
27
+ def backtrace
28
+ @backtrace ||= Backtrace.new(@exception.backtrace)
29
+ end
30
+
31
+ def to_s
32
+ "%s\n%s" % [message, backtrace]
33
+ end
34
+
35
+ attr_reader :exception
36
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Error::Exception::Backtrace
4
+ def initialize(backtrace, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
5
+ @filter = filter
6
+ @backtrace = case backtrace
7
+ when nil then []
8
+ when String then [backtrace]
9
+ when Array then backtrace.select{ |l| String === l }
10
+ end
11
+ end
12
+
13
+ def backtrace
14
+ return @backtrace unless @filter
15
+ before or outside or @backtrace
16
+ end
17
+
18
+ def to_s
19
+ backtrace.map{ |location| "\tfrom %s" % location }.join("\n")
20
+ end
21
+
22
+ private
23
+
24
+ def before
25
+ nilify(@backtrace.take_while{ |location| not reject? location })
26
+ end
27
+
28
+ def outside
29
+ nilify(@backtrace.reject{ |location| reject? location })
30
+ end
31
+
32
+ def nilify(backtrace)
33
+ backtrace.empty? ? nil : backtrace
34
+ end
35
+
36
+ def reject?(location)
37
+ location.start_with? Root
38
+ end
39
+
40
+ Root = 4.times.reduce(__FILE__){ |path, _| File.dirname(path) }
41
+ end
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Failure < Lookout::Result
4
+ is :failure
5
+
6
+ def initialize(file, line, message)
7
+ super file, line
8
+ @message = message
9
+ end
10
+
11
+ attr_reader :message
12
+
13
+ def to_s
14
+ [super, message].compact.join(': ')
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Results::Failures
4
+ autoload :Behavior, 'lookout/results/failures/behavior'
5
+ autoload :State, 'lookout/results/failures/state'
6
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Failures::Behavior < Lookout::Results::Failure
4
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Failures::State < Lookout::Results::Failure
4
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Results::Fulfilled < Lookout::Result
4
+ is :fulfilled
5
+
6
+ def initialize(file, line)
7
+ super file, line
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Runners
4
+ autoload :Console, 'lookout/runners/console'
5
+ end
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Runners::Console
4
+ def initialize(expectations = Lookout::Expectations.new)
5
+ @expectations = expectations
6
+ @run = true
7
+ end
8
+
9
+ def install
10
+ at_exit do
11
+ exit 1 unless @run and @expectations.evaluate.succeeded?
12
+ end
13
+ self
14
+ end
15
+
16
+ def expectations_eval(&block)
17
+ @expectations.instance_eval(&block)
18
+ rescue
19
+ @run = false
20
+ raise
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Stub
4
+ autoload :Method, 'lookout/stub/method'
5
+ autoload :Methods, 'lookout/stub/methods'
6
+ autoload :Object, 'lookout/stub/object'
7
+
8
+ class << self
9
+ def methods
10
+ methods = Methods.new
11
+ yield methods
12
+ ensure
13
+ methods.undefine if methods
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,105 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Stub::Method
4
+ class Values
5
+ def initialize(*values)
6
+ @values = values
7
+ @offset = -1
8
+ end
9
+
10
+ def next
11
+ @offset = [@offset + 1, @values.count - 1].min
12
+ @values[@offset]
13
+ end
14
+
15
+ def call
16
+ yield(*self.next)
17
+ end
18
+ end
19
+
20
+ class Each
21
+ def initialize(*values)
22
+ @values = values
23
+ end
24
+
25
+ def call
26
+ @values.each do |value|
27
+ yield value
28
+ end
29
+ end
30
+ end
31
+
32
+ def initialize(object, method, &body)
33
+ @object, @method, @body = object, method.to_sym, body || Nil
34
+ @yield = nil
35
+ @defined = false
36
+ end
37
+
38
+ def yield(*values)
39
+ @yield = Values.new(*values)
40
+ self
41
+ end
42
+
43
+ def each(*values)
44
+ @yield = Each.new(*values)
45
+ self
46
+ end
47
+
48
+ def define
49
+ return self if @defined
50
+ define!
51
+ @defined = true
52
+ self
53
+ end
54
+
55
+ def call(*args, &block)
56
+ @yield.call(&block) if @yield and block
57
+ @body.call(*args)
58
+ end
59
+
60
+ def undefine
61
+ return self unless @defined
62
+ undefine!
63
+ @defined = false
64
+ self
65
+ end
66
+
67
+ private
68
+
69
+ Nil = proc{ Lookout::Stub::Object.new }
70
+
71
+ def define!
72
+ meta.module_exec(@method, visibility, stash, self) do |method, visibility, stash, stub|
73
+ alias_method stash, method if
74
+ method_defined? method or private_method_defined? method
75
+ define_method method do |*args, &block|
76
+ stub.call(*args, &block)
77
+ end
78
+ send visibility, method
79
+ end
80
+ end
81
+
82
+ def undefine!
83
+ meta.module_exec(@method, stash) do |method, stash|
84
+ remove_method method
85
+ if method_defined? stash or private_method_defined? stash
86
+ alias_method method, stash
87
+ remove_method stash
88
+ end
89
+ end
90
+ end
91
+
92
+ def visibility
93
+ meta.private_method_defined?(@method) ? :private :
94
+ meta.protected_method_defined?(@method) ? :protected :
95
+ :public
96
+ end
97
+
98
+ def stash
99
+ :"__stubbed_method_#{@method}"
100
+ end
101
+
102
+ def meta
103
+ (class << @object; self; end)
104
+ end
105
+ end
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Stub::Methods
4
+ def initialize
5
+ @methods = []
6
+ end
7
+
8
+ def define(object, method, &body)
9
+ Lookout::Stub::Method.new(object, method, &body).define.tap{ |m| @methods << m }
10
+ end
11
+
12
+ def undefine
13
+ @methods.each do |method|
14
+ method.undefine
15
+ end
16
+ self
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Stub::Object
4
+ def inspect
5
+ 'stub'
6
+ end
7
+
8
+ def method_missing(method, *args)
9
+ self
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::UI
4
+ autoload :Console, 'lookout/ui/console'
5
+ autoload :Formatters, 'lookout/ui/formatters'
6
+ autoload :Silent, 'lookout/ui/silent'
7
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::UI::Console < Lookout::UI::Silent
4
+ def initialize(io = $stdout)
5
+ @io = io
6
+ end
7
+
8
+ def summarize(results, time)
9
+ return if results.succeeded?
10
+ summarize_total results, time
11
+ summarize_group results, :errors
12
+ summarize_group results, :failures
13
+ @io.flush
14
+ end
15
+
16
+ private
17
+
18
+ def summarize_total(results, time)
19
+ @io.printf "Ran %d expectations in %.3f seconds: %s\n",
20
+ results.size,
21
+ time,
22
+ [:errors, :failures, :fulfillments].inject([]){ |result, type|
23
+ next result unless (size = results.send(type).size) > 0
24
+ result << '%d %s' % [size, type]
25
+ }.join(', ')
26
+ end
27
+
28
+ def summarize_group(results, type)
29
+ group = results.send(type)
30
+ return if group.empty?
31
+ @io.puts '', type.to_s.upcase, ''
32
+ group.each do |item|
33
+ @io.puts item, ''
34
+ end
35
+ end
36
+ end