producer-core 0.1.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.
- data/.gitignore +3 -0
- data/Gemfile +5 -0
- data/Guardfile +11 -0
- data/LICENSE +30 -0
- data/Rakefile +13 -0
- data/bin/producer +5 -0
- data/features/actions/echo.feature +12 -0
- data/features/actions/sh.feature +39 -0
- data/features/cli/usage.feature +9 -0
- data/features/recipes/env.feature +9 -0
- data/features/recipes/evaluation.feature +10 -0
- data/features/recipes/source.feature +16 -0
- data/features/recipes/target.feature +12 -0
- data/features/steps/recipe_steps.rb +7 -0
- data/features/support/env.rb +0 -0
- data/features/support/env_aruba.rb +16 -0
- data/features/support/env_cucumber-doc_string.rb +23 -0
- data/features/support/ssh.rb +106 -0
- data/features/tasks/condition.feature +14 -0
- data/features/tasks/evaluation.feature +12 -0
- data/features/tests/has_env.feature +32 -0
- data/lib/producer/core/action.rb +12 -0
- data/lib/producer/core/actions/echo.rb +11 -0
- data/lib/producer/core/actions/shell_command.rb +11 -0
- data/lib/producer/core/cli.rb +43 -0
- data/lib/producer/core/condition/dsl.rb +35 -0
- data/lib/producer/core/condition.rb +26 -0
- data/lib/producer/core/env.rb +21 -0
- data/lib/producer/core/errors.rb +7 -0
- data/lib/producer/core/interpreter.rb +13 -0
- data/lib/producer/core/recipe/dsl.rb +48 -0
- data/lib/producer/core/recipe.rb +15 -0
- data/lib/producer/core/remote/environment.rb +27 -0
- data/lib/producer/core/remote.rb +40 -0
- data/lib/producer/core/task/dsl.rb +42 -0
- data/lib/producer/core/task.rb +21 -0
- data/lib/producer/core/test.rb +12 -0
- data/lib/producer/core/tests/has_env.rb +11 -0
- data/lib/producer/core/version.rb +5 -0
- data/lib/producer/core.rb +22 -0
- data/producer-core.gemspec +28 -0
- data/spec/fixtures/recipes/empty.rb +1 -0
- data/spec/fixtures/recipes/throw.rb +1 -0
- data/spec/producer/core/action_spec.rb +21 -0
- data/spec/producer/core/actions/echo_spec.rb +21 -0
- data/spec/producer/core/actions/shell_command_spec.rb +27 -0
- data/spec/producer/core/cli_spec.rb +102 -0
- data/spec/producer/core/condition/dsl_spec.rb +102 -0
- data/spec/producer/core/condition_spec.rb +96 -0
- data/spec/producer/core/env_spec.rb +54 -0
- data/spec/producer/core/interpreter_spec.rb +41 -0
- data/spec/producer/core/recipe/dsl_spec.rb +131 -0
- data/spec/producer/core/recipe_spec.rb +43 -0
- data/spec/producer/core/remote/environment_spec.rb +34 -0
- data/spec/producer/core/remote_spec.rb +87 -0
- data/spec/producer/core/task/dsl_spec.rb +131 -0
- data/spec/producer/core/task_spec.rb +91 -0
- data/spec/producer/core/test_spec.rb +30 -0
- data/spec/producer/core/tests/has_env_spec.rb +41 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/exit_helpers.rb +6 -0
- data/spec/support/fixtures_helpers.rb +7 -0
- data/spec/support/net_ssh_story_helpers.rb +17 -0
- data/spec/support/tests_helpers.rb +9 -0
- metadata +230 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Remote
|
4
|
+
class Environment
|
5
|
+
require 'forwardable'
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
def_delegator :@variables, :has_key?
|
9
|
+
|
10
|
+
def initialize(variables)
|
11
|
+
case variables
|
12
|
+
when String
|
13
|
+
@variables = parse_from_string variables
|
14
|
+
else
|
15
|
+
@variables = variables
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def parse_from_string(str)
|
22
|
+
Hash[str.each_line.map { |l| l.chomp.split '=', 2 }]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Remote
|
4
|
+
require 'etc'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
attr_accessor :hostname
|
8
|
+
|
9
|
+
def initialize(hostname)
|
10
|
+
@hostname = hostname
|
11
|
+
end
|
12
|
+
|
13
|
+
def session
|
14
|
+
@session ||= Net::SSH.start(@hostname, Etc.getlogin)
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute(command)
|
18
|
+
output = ''
|
19
|
+
session.open_channel do |channel|
|
20
|
+
channel.exec command do |ch, success|
|
21
|
+
ch.on_data do |c, data|
|
22
|
+
output << data
|
23
|
+
end
|
24
|
+
|
25
|
+
ch.on_request('exit-status') do |c, data|
|
26
|
+
exit_status = data.read_long
|
27
|
+
raise RemoteCommandExecutionError if exit_status != 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
session.loop
|
32
|
+
output
|
33
|
+
end
|
34
|
+
|
35
|
+
def environment
|
36
|
+
Environment.new(execute 'env')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Task
|
4
|
+
class DSL
|
5
|
+
class << self
|
6
|
+
def evaluate(name, env, &block)
|
7
|
+
dsl = new(&block)
|
8
|
+
dsl.evaluate(env)
|
9
|
+
Task.new(name, dsl.actions, dsl.condition)
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_action(keyword, klass)
|
13
|
+
define_method(keyword) do |*args|
|
14
|
+
@actions << klass.new(@env, *args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
define_action :echo, Actions::Echo
|
20
|
+
define_action :sh, Actions::ShellCommand
|
21
|
+
|
22
|
+
attr_accessor :actions
|
23
|
+
|
24
|
+
def initialize(&block)
|
25
|
+
@block = block
|
26
|
+
@actions = []
|
27
|
+
@condition = true
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate(env)
|
31
|
+
@env = env
|
32
|
+
instance_eval &@block
|
33
|
+
end
|
34
|
+
|
35
|
+
def condition(&block)
|
36
|
+
@condition = Condition.evaluate(@env, &block) if block
|
37
|
+
@condition
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Task
|
4
|
+
attr_reader :name, :actions, :condition
|
5
|
+
|
6
|
+
def self.evaluate(name, env, &block)
|
7
|
+
DSL.evaluate(name, env, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(name, actions = [], condition = true)
|
11
|
+
@name = name
|
12
|
+
@actions = actions
|
13
|
+
@condition = condition
|
14
|
+
end
|
15
|
+
|
16
|
+
def condition_met?
|
17
|
+
!!@condition
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# task actions
|
2
|
+
require 'producer/core/action'
|
3
|
+
require 'producer/core/actions/echo'
|
4
|
+
require 'producer/core/actions/shell_command'
|
5
|
+
|
6
|
+
# condition tests (need to be defined before the condition DSL)
|
7
|
+
require 'producer/core/test'
|
8
|
+
require 'producer/core/tests/has_env'
|
9
|
+
|
10
|
+
require 'producer/core/cli'
|
11
|
+
require 'producer/core/condition'
|
12
|
+
require 'producer/core/condition/dsl'
|
13
|
+
require 'producer/core/env'
|
14
|
+
require 'producer/core/errors'
|
15
|
+
require 'producer/core/interpreter'
|
16
|
+
require 'producer/core/recipe'
|
17
|
+
require 'producer/core/recipe/dsl'
|
18
|
+
require 'producer/core/remote'
|
19
|
+
require 'producer/core/remote/environment'
|
20
|
+
require 'producer/core/task'
|
21
|
+
require 'producer/core/task/dsl'
|
22
|
+
require 'producer/core/version'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH << lib unless $LOAD_PATH.include? lib
|
3
|
+
require 'producer/core/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'producer-core'
|
7
|
+
s.version = Producer::Core::VERSION
|
8
|
+
s.summary = "producer-core-#{Producer::Core::VERSION}"
|
9
|
+
s.description = <<-eoh.gsub(/^ +/, '')
|
10
|
+
blah
|
11
|
+
eoh
|
12
|
+
s.homepage = 'https://rubygems.org/gems/producer-core'
|
13
|
+
|
14
|
+
s.authors = 'Thibault Jouan'
|
15
|
+
s.email = 'tj@a13.fr'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split $/
|
18
|
+
s.test_files = s.files.grep /\A(spec|features)\//
|
19
|
+
s.executables = s.files.grep(/\Abin\//) { |f| File.basename(f) }
|
20
|
+
|
21
|
+
|
22
|
+
s.add_dependency 'net-ssh'
|
23
|
+
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
s.add_development_dependency 'cucumber'
|
26
|
+
s.add_development_dependency 'aruba'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# can contain tasks written in ruby language.
|
@@ -0,0 +1 @@
|
|
1
|
+
throw :recipe_code
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Action do
|
5
|
+
let(:env) { double 'env' }
|
6
|
+
let(:arguments) { [:some, :arguments] }
|
7
|
+
subject(:action) { Action.new(env, *arguments) }
|
8
|
+
|
9
|
+
describe '#env' do
|
10
|
+
it 'returns the assigned env' do
|
11
|
+
expect(action.env).to be env
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#arguments' do
|
16
|
+
it 'returns the assigned arguments' do
|
17
|
+
expect(action.arguments).to eq arguments
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Actions::Echo do
|
5
|
+
let(:env) { Env.new }
|
6
|
+
let(:text) { 'hello' }
|
7
|
+
subject(:echo) { Actions::Echo.new(env, text) }
|
8
|
+
|
9
|
+
describe '#apply' do
|
10
|
+
before do
|
11
|
+
env.output = StringIO.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'outputs the string given as argument through env.output' do
|
15
|
+
expect(env).to receive(:output).with(text)
|
16
|
+
echo.apply
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Actions::ShellCommand do
|
5
|
+
let(:env) { Env.new }
|
6
|
+
let(:command_args) { 'hello from remote host' }
|
7
|
+
let(:command) { "echo #{command_args}" }
|
8
|
+
subject(:sh) { Actions::ShellCommand.new(env, command) }
|
9
|
+
|
10
|
+
describe '#apply' do
|
11
|
+
before do
|
12
|
+
env.output = StringIO.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'delegates the call to env.remote.execute method' do
|
16
|
+
expect(env.remote).to receive(:execute).with(command)
|
17
|
+
sh.apply
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'forwards the returned output to env.output' do
|
21
|
+
allow(env.remote).to receive(:execute) { command_args }
|
22
|
+
expect(env).to receive(:output).with(command_args)
|
23
|
+
sh.apply
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe CLI do
|
5
|
+
include ExitHelpers
|
6
|
+
include FixturesHelpers
|
7
|
+
|
8
|
+
let(:recipe_file) { fixture_path_for('recipes/empty.rb') }
|
9
|
+
let(:arguments) { [recipe_file] }
|
10
|
+
subject(:cli) { CLI.new(arguments) }
|
11
|
+
|
12
|
+
describe '#initialize' do
|
13
|
+
it 'assigns $stdout as the default standard output' do
|
14
|
+
expect(cli.instance_eval { @stdout }).to be $stdout
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#arguments' do
|
19
|
+
it 'returns the assigned arguments' do
|
20
|
+
expect(cli.arguments).to eq arguments
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#run!' do
|
25
|
+
it 'checks the arguments' do
|
26
|
+
expect(cli).to receive(:check_arguments!)
|
27
|
+
cli.run!
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'processes the tasks with the interpreter' do
|
31
|
+
allow(cli.recipe).to receive(:tasks) { [:some_task] }
|
32
|
+
expect(cli.interpreter).to receive(:process).with([:some_task])
|
33
|
+
cli.run!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#check_arguments!' do
|
38
|
+
context 'when recipe argument is provided' do
|
39
|
+
it 'does not raise any error' do
|
40
|
+
expect { cli.check_arguments! }.to_not raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when recipe argument is missing' do
|
45
|
+
let(:arguments) { [] }
|
46
|
+
let(:stdout) { StringIO.new }
|
47
|
+
subject(:cli) { CLI.new(arguments, stdout) }
|
48
|
+
|
49
|
+
it 'exits with a return status of 64' do
|
50
|
+
expect { cli.check_arguments! }.to raise_error(SystemExit) { |e|
|
51
|
+
expect(e.status).to eq 64
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'prints the usage' do
|
56
|
+
trap_exit { cli.check_arguments! }
|
57
|
+
expect(stdout.string).to match /\AUsage: .+/
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#env' do
|
63
|
+
it 'builds an environment with the current recipe' do
|
64
|
+
expect(Env).to receive(:new)
|
65
|
+
cli.env
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns the env' do
|
69
|
+
env = double('env')
|
70
|
+
allow(Env).to receive(:new) { env }
|
71
|
+
expect(cli.env).to be env
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#recipe' do
|
76
|
+
it 'builds a recipe' do
|
77
|
+
expect(Recipe)
|
78
|
+
.to receive(:evaluate_from_file).with(recipe_file, cli.env)
|
79
|
+
cli.recipe
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns the recipe' do
|
83
|
+
recipe = double('recipe').as_null_object
|
84
|
+
allow(Recipe).to receive(:new) { recipe }
|
85
|
+
expect(cli.recipe).to be recipe
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#interpreter' do
|
90
|
+
it 'builds a interpreter' do
|
91
|
+
expect(Interpreter).to receive(:new)
|
92
|
+
cli.interpreter
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns the interpreter' do
|
96
|
+
interpreter = double('interpreter')
|
97
|
+
allow(Interpreter).to receive(:new) { interpreter }
|
98
|
+
expect(cli.interpreter).to be interpreter
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Condition::DSL do
|
5
|
+
let(:block) { proc { :some_condition_code } }
|
6
|
+
let(:env) { double('env') }
|
7
|
+
subject(:dsl) { Condition::DSL.new(env, &block) }
|
8
|
+
|
9
|
+
%w[has_env].each do |test|
|
10
|
+
it "has `#{test}' test defined" do
|
11
|
+
expect(dsl).to respond_to test.to_sym
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.evaluate' do
|
16
|
+
it 'builds a new DSL sandbox with given env and code' do
|
17
|
+
expect(Condition::DSL)
|
18
|
+
.to receive(:new).with(env, &block).and_call_original
|
19
|
+
Condition::DSL.evaluate(env, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'evaluates the DSL sandbox code' do
|
23
|
+
dsl = double('dsl').as_null_object
|
24
|
+
allow(Condition::DSL).to receive(:new) { dsl }
|
25
|
+
expect(dsl).to receive(:evaluate)
|
26
|
+
Condition::DSL.evaluate(env, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'builds a condition with its test and block return value' do
|
30
|
+
expect(Condition)
|
31
|
+
.to receive(:new).with(dsl.tests, :some_condition_code)
|
32
|
+
Condition::DSL.evaluate(env, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns the condition' do
|
36
|
+
condition = double('task')
|
37
|
+
allow(Condition).to receive(:new) { condition }
|
38
|
+
expect(Condition::DSL.evaluate(env, &block)).to be condition
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '.define_test' do
|
43
|
+
let(:some_test_class) { double('SomeTest class') }
|
44
|
+
|
45
|
+
before do
|
46
|
+
Condition::DSL.define_test(:some_test, some_test_class)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'defines a new test keyword' do
|
50
|
+
expect(dsl).to respond_to :some_test
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#initialize' do
|
55
|
+
it 'assigns the code' do
|
56
|
+
expect(dsl.instance_eval { @block }).to be block
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'assigns the env' do
|
60
|
+
expect(dsl.instance_eval { @env }).to be env
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'assigns no test' do
|
64
|
+
expect(dsl.tests).to be_empty
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#tests' do
|
69
|
+
it 'returns the assigned tests' do
|
70
|
+
dsl.instance_eval { @tests = [:some_test] }
|
71
|
+
expect(dsl.tests).to eq [:some_test]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#evaluate' do
|
76
|
+
it 'returns the value returned by the assigned block' do
|
77
|
+
expect(dsl.evaluate).to eq block.call
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when a defined test keyword is called' do
|
81
|
+
let(:some_test_class) { double('SomeTest class') }
|
82
|
+
let(:block) { proc { some_test :some, :args } }
|
83
|
+
|
84
|
+
before do
|
85
|
+
Condition::DSL.define_test(:some_test, some_test_class)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'builds a new test with the env and given arguments' do
|
89
|
+
expect(some_test_class).to receive(:new).with(env, :some, :args)
|
90
|
+
dsl.evaluate
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'registers the new test' do
|
94
|
+
some_test = double('SomeTest instance')
|
95
|
+
allow(some_test_class).to receive(:new) { some_test }
|
96
|
+
dsl.evaluate
|
97
|
+
expect(dsl.tests).to include(some_test)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Condition do
|
5
|
+
include TestsHelpers
|
6
|
+
|
7
|
+
let(:tests) { [test_ok, test_ko] }
|
8
|
+
subject(:condition) { Condition.new(tests) }
|
9
|
+
|
10
|
+
describe '.evaluate' do
|
11
|
+
let(:env) { double('env') }
|
12
|
+
let(:block) { proc { :some_condition_code } }
|
13
|
+
|
14
|
+
it 'delegates to DSL.evaluate' do
|
15
|
+
expect(Condition::DSL)
|
16
|
+
.to receive(:evaluate).with(env) do |&b|
|
17
|
+
expect(b.call).to eq :some_condition_code
|
18
|
+
end
|
19
|
+
Condition.evaluate(env, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the evaluated condition' do
|
23
|
+
condition = double('condition')
|
24
|
+
allow(Condition::DSL).to receive(:evaluate) { condition }
|
25
|
+
expect(Condition.evaluate(env, &block)).to be condition
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#initialize' do
|
30
|
+
it 'assigns the tests' do
|
31
|
+
expect(condition.instance_eval { @tests }).to eq tests
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'assigns nil as a default return value' do
|
35
|
+
expect(condition.instance_eval { @return_value }).to be nil
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when a return value is given as argument' do
|
39
|
+
let(:return_value) { :some_return_value }
|
40
|
+
subject(:condition) { Condition.new(tests, return_value) }
|
41
|
+
|
42
|
+
it 'assigns the return value' do
|
43
|
+
expect(condition.instance_eval { @return_value }).to eq return_value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#met?' do
|
49
|
+
context 'when all tests are successful' do
|
50
|
+
let(:tests) { [test_ok, test_ok] }
|
51
|
+
|
52
|
+
it 'returns true' do
|
53
|
+
expect(condition.met?).to be true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when one test is unsuccessful' do
|
58
|
+
let(:tests) { [test_ok, test_ko] }
|
59
|
+
|
60
|
+
it 'returns false' do
|
61
|
+
expect(condition.met?).to be false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when there are no test' do
|
66
|
+
subject(:condition) { Condition.new([], return_value) }
|
67
|
+
|
68
|
+
context 'and return value is truthy' do
|
69
|
+
let(:return_value) { :some_truthy_value }
|
70
|
+
|
71
|
+
it 'returns true' do
|
72
|
+
expect(condition.met?).to be true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'and return value is falsy' do
|
77
|
+
let(:return_value) { nil }
|
78
|
+
|
79
|
+
it 'returns false' do
|
80
|
+
expect(condition.met?).to be false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#!' do
|
87
|
+
%w[true false].each do |b|
|
88
|
+
context "when #met? return #{b}" do
|
89
|
+
it 'returns the negated #met?' do
|
90
|
+
expect(condition.!).to be !condition.met?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Env do
|
5
|
+
subject(:env) { Env.new }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
it 'assigns $stdout as the default output' do
|
9
|
+
expect(env.instance_eval { @output }).to eq $stdout
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'assigns nil as a default target' do
|
13
|
+
expect(env.target).not_to be
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#output' do
|
18
|
+
let(:stdout) { StringIO.new }
|
19
|
+
|
20
|
+
it 'writes the given string to the assigned IO with a record separator' do
|
21
|
+
env.output = stdout
|
22
|
+
env.output 'some content'
|
23
|
+
expect(stdout.string).to eq "some content\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#target' do
|
28
|
+
let(:target) { Object.new }
|
29
|
+
|
30
|
+
it 'returns the defined target' do
|
31
|
+
env.target = target
|
32
|
+
expect(env.target).to eq target
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#remote' do
|
37
|
+
it 'builds a Remote with the current target' do
|
38
|
+
env.target = 'some_hostname.example'
|
39
|
+
expect(Remote).to receive(:new).with(env.target)
|
40
|
+
env.remote
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns the remote' do
|
44
|
+
remote = double('remote')
|
45
|
+
allow(Remote).to receive(:new) { remote }
|
46
|
+
expect(env.remote).to eq remote
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'memoizes the remote' do
|
50
|
+
expect(env.remote).to be env.remote
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Interpreter do
|
5
|
+
subject(:interpreter) { Interpreter.new }
|
6
|
+
|
7
|
+
describe '#process' do
|
8
|
+
it 'processes each task' do
|
9
|
+
expect(interpreter).to receive(:process_task).with(:some_task)
|
10
|
+
interpreter.process [:some_task]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#process_task' do
|
15
|
+
let(:action) { double('action') }
|
16
|
+
let(:task) { double('task').as_null_object }
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow(task).to receive(:actions) { [action] }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when task condition is met' do
|
23
|
+
it 'applies the actions' do
|
24
|
+
expect(action).to receive(:apply)
|
25
|
+
interpreter.process_task(task)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when task condition is not met' do
|
30
|
+
before do
|
31
|
+
allow(task).to receive(:condition_met?) { false }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not apply the actions' do
|
35
|
+
expect(action).not_to receive(:apply)
|
36
|
+
interpreter.process_task(task)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|