wip-runner 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/wip/runner/renderers/erb.rb +34 -0
- data/lib/wip/runner/renderers.rb +7 -0
- data/lib/wip/runner/shell/handlers/script.rb +7 -3
- data/lib/wip/runner/shell/runner.rb +22 -4
- data/lib/wip/runner/spec/helpers/command_helpers.rb +65 -0
- data/lib/wip/runner/spec/helpers/io_helpers.rb +81 -0
- data/lib/wip/runner/spec/helpers/matchers.rb +79 -0
- data/lib/wip/runner/spec/helpers/string_helpers.rb +10 -0
- data/lib/wip/runner/spec/helpers.rb +15 -0
- data/lib/wip/runner/version.rb +1 -1
- data/lib/wip/runner.rb +1 -0
- metadata +8 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c64b6f78c5e647a9466ebd60985ac716ded1bf9f
|
4
|
+
data.tar.gz: ef987404e179109f39e0d70bef78b7926428b21f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 289d7586526bc1634e9303ddd1d9dde0b4110f1434fd270e059b1a7ab35af9c4407efef24bc14739bc598d5d13a806c79bc355cefd3f8d896cf7b36dd5333235
|
7
|
+
data.tar.gz: df6f588f1eac45e2e11567812981b36e96162cc3c1b5e95cd68a4a3eeed741980d1a27250fa5fe14021a12362d42fd56fdc2925f81214088a5c2e30b3d162ef8
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module WIP
|
4
|
+
module Runner
|
5
|
+
module Renderers
|
6
|
+
module ERB
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
def render(template, context)
|
12
|
+
if (file = File.join("#{self.class.templates}/#{template}.erb")) && File.exist?(file)
|
13
|
+
template = File.read(file)
|
14
|
+
end
|
15
|
+
::ERB.new(clean(template)).result(context)
|
16
|
+
end
|
17
|
+
|
18
|
+
def clean(string)
|
19
|
+
return if string.nil?
|
20
|
+
|
21
|
+
indent = (string.scan(/^[ \t]*(?=\S)/).min || '').size
|
22
|
+
string.gsub(/^[ \t]{#{indent}}/, '').strip
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
def templates(value = nil)
|
27
|
+
@templates = value unless value.nil?
|
28
|
+
@templates
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -15,9 +15,13 @@ module WIP
|
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
18
|
-
def description
|
19
|
-
|
20
|
-
|
18
|
+
def description(format = :text)
|
19
|
+
case format
|
20
|
+
when :markdown
|
21
|
+
"```\n#{@content}\n```"
|
22
|
+
else
|
23
|
+
@content
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
27
|
def execute(io, env, &block)
|
@@ -17,7 +17,13 @@ module WIP
|
|
17
17
|
@arguments = arguments
|
18
18
|
@options = options
|
19
19
|
|
20
|
-
|
20
|
+
if markdown?
|
21
|
+
@io.indent do
|
22
|
+
@tasks.each do |task|
|
23
|
+
evaluate(task)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
21
27
|
@tasks.each do |task|
|
22
28
|
evaluate(task)
|
23
29
|
end
|
@@ -41,8 +47,8 @@ module WIP
|
|
41
47
|
|
42
48
|
task.shells.each do |shell|
|
43
49
|
section("Shell #{shell.type.downcase}") do
|
44
|
-
@io.newline
|
45
50
|
send(:"#{prefix}_shell", shell)
|
51
|
+
@io.newline
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
@@ -108,8 +114,20 @@ module WIP
|
|
108
114
|
# ---
|
109
115
|
|
110
116
|
def section(heading, &block)
|
111
|
-
|
112
|
-
|
117
|
+
if markdown?
|
118
|
+
@io.say "- [ ] #{heading}..."
|
119
|
+
@io.indent(&block)
|
120
|
+
else
|
121
|
+
yield
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def format
|
126
|
+
@options.format ? @options.format.intern : :text
|
127
|
+
end
|
128
|
+
|
129
|
+
def markdown?
|
130
|
+
format == :markdown
|
113
131
|
end
|
114
132
|
|
115
133
|
# $ wip-runner x --format=markdown
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner::Spec
|
3
|
+
module Helpers::CommandHelpers
|
4
|
+
def define_command(&block)
|
5
|
+
klass = Class.new(WIP::Runner::Command)
|
6
|
+
klass.instance_exec do
|
7
|
+
def name
|
8
|
+
'Command'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
klass.class_exec(&block)
|
12
|
+
klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def example_command(implementation)
|
16
|
+
ExampleCommands.const_get(implementation).new(io)
|
17
|
+
end
|
18
|
+
|
19
|
+
module ExampleCommands
|
20
|
+
class Simple < WIP::Runner::Command
|
21
|
+
def execute(args, options)
|
22
|
+
@executed = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def executed?
|
26
|
+
!! @executed
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class WithOptions < Simple
|
31
|
+
options do |parser, config|
|
32
|
+
config.flagged = false
|
33
|
+
|
34
|
+
parser.on('-f', '--flag', 'Option 1') do
|
35
|
+
config.flagged = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :flagged
|
40
|
+
|
41
|
+
def execute(args, options)
|
42
|
+
super
|
43
|
+
@flagged = options.flagged
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class WithArguments < Simple
|
48
|
+
argument :arg_01, { overview: 'Argument 1' }
|
49
|
+
argument :arg_02, { overview: 'Argument 2' }
|
50
|
+
end
|
51
|
+
|
52
|
+
class WithNested < Simple ; end
|
53
|
+
|
54
|
+
class WithNested::Nested < Simple
|
55
|
+
overview 'A nested command'
|
56
|
+
|
57
|
+
def execute(args, options)
|
58
|
+
super
|
59
|
+
@io.say 'running nested command...'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner::Spec
|
3
|
+
module Helpers::IOHelpers
|
4
|
+
def io
|
5
|
+
@io ||= CustomHighLine.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def simulate(pairs = nil)
|
9
|
+
unless pairs.nil?
|
10
|
+
@simulated = pairs.inject(@simulated || {}) do |memo, (q, a)|
|
11
|
+
memo[q] = a ; memo
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if block_given?
|
16
|
+
begin
|
17
|
+
originput = io.instance_variable_get(:@input)
|
18
|
+
simulator = Simulator.new(@simulated.values, (@simulated.keys == ['*']))
|
19
|
+
io.instance_variable_set(:@input, simulator)
|
20
|
+
|
21
|
+
@simulated.keys.each do |question|
|
22
|
+
# NOTE: the "|default|" is stripped because that is added
|
23
|
+
# later by the Question instance, in time for a call to #say.
|
24
|
+
if question.is_a?(Array)
|
25
|
+
expect(io).to receive(:ask)
|
26
|
+
.with(*question)
|
27
|
+
.and_call_original
|
28
|
+
else
|
29
|
+
question = question.sub(/:\s\|.*\Z/, ': ')
|
30
|
+
expect(io).to receive(:ask)
|
31
|
+
.with(question)
|
32
|
+
.and_call_original
|
33
|
+
end unless question == '*'
|
34
|
+
end
|
35
|
+
|
36
|
+
yield
|
37
|
+
ensure
|
38
|
+
io.instance_variable_set(:@input, originput)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
class CustomHighLine < HighLine
|
46
|
+
# Strips the same-line indicating, trailing space from questions in order
|
47
|
+
# to print the newline in specs (that would come from user input).
|
48
|
+
def ask(question, answer_type = String, &block)
|
49
|
+
super("#{question.rstrip}", answer_type, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Strips double spaces between question and default.
|
53
|
+
def say(statement)
|
54
|
+
# puts statement.to_s.inspect
|
55
|
+
super statement.to_s.gsub(/:\s{2,}\|/, ': |')
|
56
|
+
end
|
57
|
+
|
58
|
+
# Strips formatting for specs.
|
59
|
+
def color(string, *colors)
|
60
|
+
string
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# adapted from https://gist.github.com/194554
|
65
|
+
class Simulator
|
66
|
+
def initialize(values, all = false)
|
67
|
+
@values = values.map { |s| s.nil? ? '' : s }
|
68
|
+
@all = all
|
69
|
+
end
|
70
|
+
|
71
|
+
def gets
|
72
|
+
@all ? @values.first : @values.shift
|
73
|
+
end
|
74
|
+
|
75
|
+
def eof?
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner::Spec
|
3
|
+
module Helpers::Matchers
|
4
|
+
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}")
|
8
|
+
end
|
9
|
+
|
10
|
+
class ShowMatcher < RSpec::Matchers::BuiltIn::Output
|
11
|
+
def initialize(example, expected, output, match)
|
12
|
+
super(expected)
|
13
|
+
@example = example
|
14
|
+
@output = output
|
15
|
+
@match = match
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(block)
|
19
|
+
@block = block
|
20
|
+
return false unless Proc === block
|
21
|
+
|
22
|
+
@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
|
30
|
+
|
31
|
+
if @match == :partial
|
32
|
+
values_match?(/#{Regexp.escape(@expected)}/, @actual)
|
33
|
+
else
|
34
|
+
values_match?(@expected, @actual)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def description
|
39
|
+
"#{@stream_capturer.name} to receive the following content (#{@match} match):"
|
40
|
+
end
|
41
|
+
|
42
|
+
def failure_message
|
43
|
+
[
|
44
|
+
"expected #{description}",
|
45
|
+
"Expected:",
|
46
|
+
"#{@expected}\n",
|
47
|
+
"Actual:",
|
48
|
+
"#{@actual}\n\n"
|
49
|
+
].join("\n\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_highline
|
53
|
+
@stream_capturer = CaptureHighline
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
# @private
|
58
|
+
module CaptureHighline
|
59
|
+
def self.name
|
60
|
+
'highline'
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.capture(io, block)
|
64
|
+
captured_stream = StringIO.new
|
65
|
+
|
66
|
+
original_stream = io.instance_variable_get(:'@output')
|
67
|
+
io.instance_variable_set(:'@output', captured_stream)
|
68
|
+
|
69
|
+
block.call
|
70
|
+
|
71
|
+
captured_stream.string
|
72
|
+
ensure
|
73
|
+
io.instance_variable_set(:'@output', captured_stream)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner
|
3
|
+
module Spec
|
4
|
+
module Helpers ; end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Dir[File.expand_path('../helpers/*.rb', __FILE__)].each { |f| require(f) }
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.include WIP::Runner::Spec::Helpers::Matchers
|
12
|
+
config.include WIP::Runner::Spec::Helpers::CommandHelpers
|
13
|
+
config.include WIP::Runner::Spec::Helpers::IOHelpers
|
14
|
+
config.include WIP::Runner::Spec::Helpers::StringHelpers
|
15
|
+
end
|
data/lib/wip/runner/version.rb
CHANGED
data/lib/wip/runner.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wip-runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Corey Innis
|
@@ -95,6 +95,8 @@ files:
|
|
95
95
|
- lib/wip/runner/errors.rb
|
96
96
|
- lib/wip/runner/options.rb
|
97
97
|
- lib/wip/runner/parser.rb
|
98
|
+
- lib/wip/runner/renderers.rb
|
99
|
+
- lib/wip/runner/renderers/erb.rb
|
98
100
|
- lib/wip/runner/shell.rb
|
99
101
|
- lib/wip/runner/shell/handlers.rb
|
100
102
|
- lib/wip/runner/shell/handlers/base.rb
|
@@ -102,6 +104,11 @@ files:
|
|
102
104
|
- lib/wip/runner/shell/handlers/system.rb
|
103
105
|
- lib/wip/runner/shell/runner.rb
|
104
106
|
- lib/wip/runner/shell/task.rb
|
107
|
+
- lib/wip/runner/spec/helpers.rb
|
108
|
+
- lib/wip/runner/spec/helpers/command_helpers.rb
|
109
|
+
- lib/wip/runner/spec/helpers/io_helpers.rb
|
110
|
+
- lib/wip/runner/spec/helpers/matchers.rb
|
111
|
+
- lib/wip/runner/spec/helpers/string_helpers.rb
|
105
112
|
- lib/wip/runner/version.rb
|
106
113
|
- lib/wip/runner/workflow.rb
|
107
114
|
- lib/wip/runner/workflow/builder.rb
|