lookout 2.1.4 → 2.2.0

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.
@@ -24,16 +24,7 @@ module Lookout
24
24
  return nil, nil unless match = /\A(.*):(\d+)(?::in .*)?\z/.match(location)
25
25
  [match[1], match[2].to_i]
26
26
  end
27
-
28
- def runner(runner = nil)
29
- return @runner = runner if runner
30
- @runner ||= Lookout::Runners::Console.new.install
31
- end
32
27
  end
33
28
  end
34
29
 
35
30
  require 'lookout/object'
36
-
37
- def Expectations(&block)
38
- Lookout.runner.expectations_eval(&block)
39
- end
@@ -9,7 +9,7 @@ class Lookout::Diff::Algorithms::Difflib::Position
9
9
  new(Lookout::Diff::Range.new(from),
10
10
  to,
11
11
  block_given? ?
12
- to.indexes.reduce({}){ |j, (k, v)| j[k] = yield(k); j } :
12
+ to.indexes.reduce({}){ |j, (k, _)| j[k] = yield(k); j } :
13
13
  {})
14
14
  end
15
15
  end
@@ -6,7 +6,7 @@ class Lookout::Equalities::StandardError < Lookout::Equalities::Object
6
6
  def equal?(expected, actual)
7
7
  expected.equal?(actual) or
8
8
  ((actual.respond_to? :message rescue false) and
9
- ((Regexp === expected.message and expected.message === actual.message) or
9
+ ((regexp(expected) and regexp(expected) === actual.message) or
10
10
  expected.message == actual.message))
11
11
  end
12
12
 
@@ -19,8 +19,14 @@ class Lookout::Equalities::StandardError < Lookout::Equalities::Object
19
19
  private
20
20
 
21
21
  def format(expected, actual)
22
- Regexp === expected.message ?
23
- '%p≠#<%s: %p>' % [actual, expected.class, expected.message] :
22
+ regexp(expected) ?
23
+ '%p≠#<%s: %p>' % [actual, expected.class, regexp(expected)] :
24
24
  super
25
25
  end
26
+
27
+ def regexp(expected)
28
+ return expected.message if Regexp === expected.message
29
+ return Regexp.new(expected.message) if expected.message =~ /\A\(\?-[mix]+:.*\)\z/
30
+ nil
31
+ end
26
32
  end
@@ -2,12 +2,11 @@
2
2
 
3
3
  class Lookout::Expectations
4
4
  autoload :Behavior, 'lookout/expectations/behavior'
5
+ autoload :Line, 'lookout/expectations/line'
5
6
  autoload :State, 'lookout/expectations/state'
6
7
 
7
- def initialize(results = Lookout::Results::Unsuccessful.new, line = nil)
8
- @results, @line = results, line
9
- @previous = nil
10
- @ran_previous = false
8
+ def initialize(results = Lookout::Results.new)
9
+ @results = results
11
10
  end
12
11
 
13
12
  def mock
@@ -39,26 +38,12 @@ class Lookout::Expectations
39
38
  end
40
39
 
41
40
  def expect(expected, &block)
42
- expectation = Lookout::Expectation.on(expected, *Lookout.location(caller.first), &block)
43
- if @line
44
- unless @ran_previous
45
- if @previous and @previous.line <= @line and expectation.line > @line
46
- @results << @previous.evaluate
47
- @ran_previous = true
48
- @previous = nil
49
- else
50
- @previous = expectation
51
- end
52
- end
53
- else
54
- @results << expectation.evaluate
55
- end
41
+ @results << Lookout::Expectation.on(expected, *Lookout.location(caller.first), &block).evaluate
56
42
  self
57
43
  end
58
44
 
59
45
  # TODO: It would be great if this method wasn’t necessary.
60
46
  def flush
61
- @results << @previous.evaluate if @previous
62
47
  self
63
48
  end
64
49
  end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Expectations::Line < Lookout::Expectations
4
+ def initialize(line, results = Lookout::Results.new)
5
+ super results
6
+ @line = line
7
+ @previous = nil
8
+ @ran_previous = false
9
+ end
10
+
11
+ def expect(expected)
12
+ return self if @ran_previous
13
+ expectation = Lookout::Expectation.on(expected, *Lookout.location(caller.first), &Proc.new)
14
+ if @previous and @previous.line <= @line and expectation.line > @line
15
+ flush
16
+ @previous = nil
17
+ @ran_previous = true
18
+ else
19
+ @previous = expectation
20
+ end
21
+ self
22
+ end
23
+
24
+ # TODO: It would be great if this method wasn’t necessary.
25
+ def flush
26
+ @results << @previous.evaluate if @previous
27
+ self
28
+ end
29
+ end
@@ -14,7 +14,7 @@ class Lookout::Rake::Tasks::Gem < Rake::TaskLib
14
14
  def define
15
15
  desc 'Build %s' % specification.file_name
16
16
  task :build => specification.file_name
17
- file specification.file_name => specification.files do
17
+ file specification.file_name => [specification.loaded_from] + specification.files do
18
18
  when_writing 'Building %s' % specification.file_name do
19
19
  require 'rubygems' unless defined? Gem
20
20
  require 'rubygems/installer' unless defined? Gem::Builder
@@ -26,7 +26,7 @@ class Lookout::Rake::Tasks::Gem < Rake::TaskLib
26
26
  task :check => :build do
27
27
  require 'rubygems' unless defined? Gem
28
28
  require 'rubygems/installer' unless defined? Gem::Installer
29
- checkdir = specification.full_name
29
+ checkdir = File.join(Lookout::Rake::Tasks.top_srcdir, specification.full_name)
30
30
  Gem::Installer.new(specification.file_name, :unpack => true).unpack checkdir
31
31
  sh 'rake --rakefile %s/Rakefile -s test' % checkdir
32
32
  rm_r checkdir
@@ -2,18 +2,21 @@
2
2
 
3
3
  require 'lookout'
4
4
 
5
+ results = Lookout::Results.new
6
+ line = ENV['LINE'] && ENV['LINE'].to_i
7
+ runner = Lookout::Runners::Console.new(results,
8
+ line ?
9
+ Lookout::Expectations::Line.new(line, results) :
10
+ Lookout::Expectations.new(results),
11
+ Lookout::UI::Console.new(results)).install
5
12
  only_load = false
6
13
  ARGV.each do |arg|
7
- begin
8
- if not only_load and arg == '--'
9
- only_load = true
10
- elsif not only_load and arg =~ /\A-r(.*)/
11
- require $1
12
- else
13
- load arg
14
- end
15
- rescue SyntaxError => e
16
- raise e unless matches = %r{\A(.*?:\d+): (.*)}m.match(e.message)
17
- raise SyntaxError, matches[2], [matches[1]]
14
+ if not only_load and arg == '--'
15
+ only_load = true
16
+ elsif not only_load and arg =~ /\A-r(.*)/
17
+ require $1
18
+ else
19
+ runner.load arg
18
20
  end
19
21
  end
22
+ runner.exit
@@ -1,11 +1,25 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- module Lookout::Results
3
+ class Lookout::Results
4
4
  autoload :Error, 'lookout/results/error'
5
5
  autoload :Failure, 'lookout/results/failure'
6
6
  autoload :Failures, 'lookout/results/failures'
7
7
  autoload :Fulfilled, 'lookout/results/fulfilled'
8
-
9
- autoload :Instance, 'lookout/results/instance'
10
8
  autoload :Unsuccessful, 'lookout/results/unsuccessful'
9
+
10
+ def initialize
11
+ @listeners = []
12
+ end
13
+
14
+ def on_new(&block)
15
+ @listeners << block
16
+ self
17
+ end
18
+
19
+ def <<(result)
20
+ @listeners.each do |listener|
21
+ listener.call result
22
+ end
23
+ self
24
+ end
11
25
  end
@@ -25,12 +25,10 @@ class Lookout::Results::Error::Exception
25
25
  end
26
26
 
27
27
  def backtrace
28
- @backtrace ||= Backtrace.new(@exception.backtrace)
28
+ @backtrace ||= Backtrace.new(@exception.backtrace, SystemStackError === @exception)
29
29
  end
30
30
 
31
31
  def to_s
32
32
  "%s\n%s" % [message, backtrace]
33
33
  end
34
-
35
- attr_reader :exception
36
34
  end
@@ -1,26 +1,26 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  class Lookout::Results::Error::Exception::Backtrace
4
- def initialize(backtrace, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
5
- @filter = filter
4
+ def initialize(backtrace, trim, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
6
5
  @backtrace = case backtrace
7
6
  when nil then []
8
7
  when String then [backtrace]
9
8
  when Array then backtrace.select{ |l| String === l }
10
9
  end
11
- end
12
-
13
- def backtrace
14
- return @backtrace unless @filter
15
- before or outside or @backtrace
10
+ @trim, @filter = trim, filter
16
11
  end
17
12
 
18
13
  def to_s
19
- backtrace.map{ |location| "\tfrom %s" % location }.join("\n")
14
+ trim(backtrace.map{ |location| "\tfrom %s" % location }).join("\n")
20
15
  end
21
16
 
22
17
  private
23
18
 
19
+ def backtrace
20
+ return @backtrace unless @filter
21
+ before or outside or @backtrace
22
+ end
23
+
24
24
  def before
25
25
  nilify(@backtrace.take_while{ |location| not reject? location })
26
26
  end
@@ -37,5 +37,14 @@ private
37
37
  location.start_with? Root
38
38
  end
39
39
 
40
+ def trim(locations)
41
+ return locations unless @trim and locations.length > Head + Tail + 5
42
+ locations[0...Head] +
43
+ ["\t ... %d levels ..." % (locations.length - Head - Tail)] +
44
+ locations[-Tail..-1]
45
+ end
46
+
40
47
  Root = 4.times.reduce(__FILE__){ |path, _| File.dirname(path) }
48
+ Head = 8
49
+ Tail = 5
41
50
  end
@@ -1,8 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- class Lookout::Results::Unsuccessful
4
- include Lookout::Results::Instance
5
-
3
+ class Lookout::Results::Unsuccessful < Lookout::Results
6
4
  include Enumerable
7
5
 
8
6
  def initialize
@@ -23,10 +21,6 @@ class Lookout::Results::Unsuccessful
23
21
  self
24
22
  end
25
23
 
26
- def succeeded?
27
- @unsuccessful.empty?
28
- end
29
-
30
24
  def errors
31
25
  select{ |result| Lookout::Results::Error === result }
32
26
  end
@@ -2,4 +2,5 @@
2
2
 
3
3
  module Lookout::Runners
4
4
  autoload :Console, 'lookout/runners/console'
5
+ autoload :Trackers, 'lookout/runners/trackers'
5
6
  end
@@ -1,24 +1,41 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  class Lookout::Runners::Console
4
- def initialize(results = Lookout::Results::Unsuccessful.new,
5
- expectations = Lookout::Expectations.new(results,
6
- ENV['LINE'] && ENV['LINE'].to_i),
4
+ def initialize(results = Lookout::Results.new,
5
+ expectations = Lookout::Expectations.new(results),
7
6
  ui = Lookout::UI::Console.new(results))
8
7
  @results, @expectations, @ui = results, expectations, ui
9
8
  @ui.start
9
+ @failed = Lookout::Runners::Trackers::Failure.new(@results)
10
10
  end
11
11
 
12
12
  def install
13
- at_exit do
14
- next if $!
15
- @expectations.flush
16
- @ui.summarize
17
- exit 1 unless @results.succeeded?
13
+ Kernel.module_exec(self) do |runner|
14
+ define_method :Expectations do |&block|
15
+ runner.expectations_eval(&block)
16
+ end
18
17
  end
19
18
  self
20
19
  end
21
20
 
21
+ def load(file)
22
+ expectations_eval do
23
+ begin
24
+ load file
25
+ rescue SyntaxError => e
26
+ raise unless matches = %r{\A(.*?:\d+): (.*)}m.match(e.message)
27
+ raise SyntaxError, matches[2], [matches[1]]
28
+ end
29
+ end
30
+ end
31
+
32
+ def exit
33
+ @expectations.flush
34
+ @ui.flush
35
+ super 1 if @failed.failed?
36
+ self
37
+ end
38
+
22
39
  def expectations_eval(&block)
23
40
  @expectations.instance_eval(&block)
24
41
  rescue Interrupt, NoMemoryError, SignalException, SystemExit
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Runners::Trackers
4
+ autoload :Failure, 'lookout/runners/trackers/failure'
5
+ end
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Runners::Trackers::Failure
4
+ def initialize(results)
5
+ @failed = false
6
+ results.on_new do |result|
7
+ @failed = !(Lookout::Results::Fulfilled === result) unless @failed
8
+ end
9
+ end
10
+
11
+ def failed?
12
+ @failed
13
+ end
14
+ end
@@ -1,46 +1,19 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  class Lookout::UI::Console
4
- def initialize(results, io = $stdout)
4
+ def initialize(results, io = $stderr)
5
5
  @results, @io = results, io
6
- @count = 0
7
- results.on_new do
8
- @count += 1
6
+ results.on_new do |result|
7
+ @io.puts result unless Lookout::Results::Fulfilled === result
9
8
  end
10
9
  end
11
10
 
12
11
  def start
13
- @start = Time.now.to_f
12
+ self
14
13
  end
15
14
 
16
- def summarize
17
- return if @results.succeeded?
18
- summarize_total
19
- summarize_group :errors
20
- summarize_group :failures
15
+ def flush
21
16
  @io.flush
22
- end
23
-
24
- private
25
-
26
- def summarize_total
27
- @io.printf "Ran %d expectations in %.3f seconds: %s\n",
28
- @count,
29
- Time.now.to_f - @start,
30
- [['errors', @results.errors.size],
31
- ['failures', @results.failures.size]].tap{ |types|
32
- types << ['fulfillments', @count - types.reduce(0){ |sum, pair| sum + pair[1] }]
33
- }.select{ |type, size| size > 0 }.
34
- map{ |type, size| '%d %s' % [size, type] }.
35
- join(', ')
36
- end
37
-
38
- def summarize_group(type)
39
- group = @results.send(type)
40
- return if group.empty?
41
- @io.puts '', type.to_s.upcase, ''
42
- group.each do |item|
43
- @io.puts item, ''
44
- end
17
+ self
45
18
  end
46
19
  end
@@ -4,6 +4,6 @@ class Lookout::UI::Silent
4
4
  def start
5
5
  end
6
6
 
7
- def summarize
7
+ def flush
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Lookout
4
- Version = '2.1.4'
4
+ Version = '2.2.0'
5
5
  end
@@ -1,10 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  Expectations do
4
- expect Lookout.runner.to.receive.expectations_eval do
5
- Expectations{ }
6
- end
7
-
8
4
  expect [nil, nil] do
9
5
  Lookout.location('abc')
10
6
  end