wip-runner 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,19 @@
1
1
  module WIP
2
2
  module Runner::Spec
3
3
  module Helpers::Matchers
4
+ # TODO: fix the following message:
5
+ # expected block to not STDCOMBINED to receive the following content (partial match):, but output "- VARIABLE: |value from ENV|\n\necho $VARIABLE\n\n> value from user"
4
6
  def show(expected, options = {})
5
- output = options[:output] || :highline
6
- match = options[:match] || :full # :match => [:full | :partial]
7
- ShowMatcher.new(self, strip_heredoc(expected).strip, output, match).send(:"to_#{output}")
7
+ stream = options[:to] || :combined # :to => [:out | :err]
8
+ match = options[:match] || :full # :match => [:full | :partial]
9
+ ShowMatcher.new(self, strip_heredoc(expected).strip, stream, match)
8
10
  end
9
11
 
10
12
  class ShowMatcher < RSpec::Matchers::BuiltIn::Output
11
- def initialize(example, expected, output, match)
13
+ def initialize(example, expected, stream, match)
12
14
  super(expected)
13
15
  @example = example
14
- @output = output
16
+ @stream = stream
15
17
  @match = match
16
18
  end
17
19
 
@@ -20,13 +22,8 @@ module WIP
20
22
  return false unless Proc === block
21
23
 
22
24
  @expected = @expected.strip
23
-
24
- if @output == :highline
25
- @actual = @stream_capturer.capture(@example.io, block)
26
- @actual = @example.strip_heredoc(@actual).strip
27
- else
28
- @actual = @stream_capturer.capture(block).strip
29
- end
25
+ @actual = Capturer.capture(@example.ui, @stream, block)
26
+ @actual = @example.strip_heredoc(@actual).strip
30
27
 
31
28
  if @match == :partial
32
29
  values_match?(/#{Regexp.escape(@expected)}/, @actual)
@@ -36,7 +33,7 @@ module WIP
36
33
  end
37
34
 
38
35
  def description
39
- "#{@stream_capturer.name} to receive the following content (#{@match} match):"
36
+ "STD#{@stream.upcase} to receive the following content (#{@match} match):"
40
37
  end
41
38
 
42
39
  def failure_message
@@ -49,28 +46,33 @@ module WIP
49
46
  ].join("\n\n")
50
47
  end
51
48
 
52
- def to_highline
53
- @stream_capturer = CaptureHighline
54
- self
55
- end
56
-
57
49
  # @private
58
- module CaptureHighline
59
- def self.name
60
- 'highline'
61
- end
50
+ module Capturer
51
+ def self.capture(ui, stream, block)
52
+ captured = StringIO.new
62
53
 
63
- def self.capture(io, block)
64
- captured_stream = StringIO.new
54
+ mappings = {}.tap do |h|
55
+ if stream == :combined
56
+ out = ui.send(:out)
57
+ err = ui.send(:err)
58
+ h[out] = out.instance_variable_get(:'@output')
59
+ h[err] = err.instance_variable_get(:'@output')
60
+ else
61
+ io = ui.send(stream)
62
+ h[io] = io.instance_variable_get(:'@output')
63
+ end
64
+ end
65
65
 
66
- original_stream = io.instance_variable_get(:'@output')
67
- io.instance_variable_set(:'@output', captured_stream)
66
+ mappings.each do |io, original|
67
+ io.instance_variable_set(:'@output', captured)
68
+ end
68
69
 
69
70
  block.call
70
-
71
- captured_stream.string
71
+ captured.string
72
72
  ensure
73
- io.instance_variable_set(:'@output', captured_stream)
73
+ mappings.each do |io, original|
74
+ io.instance_variable_set(:'@output', original)
75
+ end
74
76
  end
75
77
  end
76
78
  end
@@ -2,7 +2,7 @@ module WIP
2
2
  module Runner::Spec
3
3
  module Helpers::StringHelpers
4
4
  def strip_heredoc(string)
5
- indent = string.scan(/^[ \t]*(?=\S)/).min.size || 0
5
+ indent = (string.scan(/^[ \t]*(?=\S)/).min || '').size || 0
6
6
  string.gsub(/^[ \t]{#{indent}}/, '')
7
7
  end
8
8
  end
@@ -0,0 +1,93 @@
1
+ module WIP
2
+ module Runner::Spec
3
+ module Helpers::UIHelpers
4
+ def ui
5
+ @ui ||= CustomUI.new($stdin, StringIO.new, StringIO.new)
6
+ end
7
+
8
+ def simulate(pairs = nil)
9
+ unless pairs.nil?
10
+ @simulated = pairs.inject(@simulated || []) do |memo, pair|
11
+ memo << pair ; memo
12
+ end
13
+ end
14
+
15
+ if block_given?
16
+ highline = ui.err
17
+ original = highline.instance_variable_get(:@input)
18
+
19
+ begin
20
+ if @simulated
21
+ keys = @simulated.map { |pair| pair[0] }
22
+ values = @simulated.map { |pair| pair[1] }
23
+ simulator = Simulator.new(values, (@simulated[0][0] == '*'))
24
+ highline.instance_variable_set(:@input, simulator)
25
+
26
+ keys.each do |question|
27
+ # NOTE: the "|default|" is stripped because that is added
28
+ # later by the Question instance, in time for a call to #say.
29
+ if question.is_a?(Array)
30
+ expect(highline).to receive(:ask)
31
+ .with(*question)
32
+ .and_call_original
33
+ else
34
+ question = question.sub(/:\s\|.*\Z/, ': ')
35
+ expect(highline).to receive(:ask)
36
+ .with(question)
37
+ .and_call_original
38
+ end unless question == '*'
39
+ end
40
+ end
41
+
42
+ yield
43
+ ensure
44
+ highline.instance_variable_set(:@input, original)
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ class CustomUI < WIP::Runner::UI
52
+ def initialize(input, out, err)
53
+ @out = CustomLine.new(input, out, nil, nil, 2, 0)
54
+ @err = CustomLine.new(input, err, nil, nil, 2, 0)
55
+ end
56
+ end
57
+
58
+ class CustomLine < HighLine
59
+ # Strips the same-line indicating, trailing space from questions in order
60
+ # to print the newline in specs (that would come from user input).
61
+ def ask(question, answer_type = String, &block)
62
+ super("#{question.rstrip}", answer_type, &block)
63
+ end
64
+
65
+ # Strips double spaces between question and default.
66
+ def say(statement)
67
+ super(statement.to_s.gsub(/:\s{2,}\|/, ': |'))
68
+ end
69
+
70
+ # Strips formatting for specs.
71
+ def color(string, *colors)
72
+ string
73
+ end
74
+ end
75
+
76
+ # adapted from https://gist.github.com/194554
77
+ class Simulator
78
+ def initialize(values, all = false)
79
+ @values = values.map { |s| s.nil? ? '' : s }
80
+ @all = all
81
+ end
82
+
83
+ def gets
84
+ @all ? @values.first : @values.shift
85
+ end
86
+
87
+ def eof?
88
+ false
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -10,6 +10,6 @@ Dir[File.expand_path('../helpers/*.rb', __FILE__)].each { |f| require(f) }
10
10
  RSpec.configure do |config|
11
11
  config.include WIP::Runner::Spec::Helpers::Matchers
12
12
  config.include WIP::Runner::Spec::Helpers::CommandHelpers
13
- config.include WIP::Runner::Spec::Helpers::IOHelpers
13
+ config.include WIP::Runner::Spec::Helpers::UIHelpers
14
14
  config.include WIP::Runner::Spec::Helpers::StringHelpers
15
15
  end
@@ -0,0 +1,65 @@
1
+ require 'highline'
2
+
3
+ module WIP
4
+ module Runner
5
+ class UI
6
+ def initialize(input = $stdin, out = $stdout, err = $stderr)
7
+ @out = HighLine.new(input, out, nil, nil, 2, 0)
8
+ @err = HighLine.new(input, err, nil, nil, 2, 0)
9
+ @output = @out
10
+ end
11
+
12
+ def err
13
+ if block_given?
14
+ current = @output
15
+ @output = @err
16
+ result = yield
17
+ @output = current
18
+ result
19
+ else
20
+ @err
21
+ end
22
+ end
23
+
24
+ def out
25
+ if block_given?
26
+ current = @output
27
+ @output = @out
28
+ result = yield
29
+ @output = current
30
+ result
31
+ else
32
+ @out
33
+ end
34
+ end
35
+
36
+ def indent(*args, &block)
37
+ increase = args.shift || 1
38
+ @out.indent_level += increase
39
+ @err.indent_level += increase
40
+ @output.indent(0, *args, &block)
41
+ @out.indent_level -= increase
42
+ @err.indent_level -= increase
43
+ end
44
+
45
+ def indent_level=(level)
46
+ @out.indent_level = level
47
+ @err.indent_level = level
48
+ end
49
+
50
+ protected
51
+
52
+ def method_missing(method_name, *args, &block)
53
+ if @output.respond_to?(method_name)
54
+ @output.send(method_name, *args, &block)
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ def respond_to_missing?(method_name, include_private = false)
61
+ @output.respond_to?(method_name) || super
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,5 @@
1
1
  module WIP
2
2
  module Runner
3
- VERSION = "0.3.4"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end