wip-runner 0.3.4 → 0.4.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.
@@ -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