foreplay 0.9.8 → 0.9.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12c397ff52837a1e5fd7a68631639acb440e4026
4
- data.tar.gz: 44f1d0cce1ce602e68ab2fa64d42aa4961fad32f
3
+ metadata.gz: 54fa14c8cd58bcbcfa3d6ae58721785d2cbedf60
4
+ data.tar.gz: 78bfd857d56736431725d9d3b9eddc307f327c85
5
5
  SHA512:
6
- metadata.gz: ad5695f9428ef9f84713e98a2574a9404f66fb28cdb3e4140076202d76d19141469f6cb67ad20a9ba5f03f2e7c47cb7ce2c82d363b02d00f4d6b72640916b792
7
- data.tar.gz: a732fa61abbd044584baf912d7c3787e3814ad3ea4259ea69add455f615fede9c8647ebb9da59ed1601aeb6c5a3cff65f1d05ad2bd212b0c8965b32d3bcc86df
6
+ metadata.gz: df13a59675a8e854d44d4b09c85723af3d8ef482c1fd726a5f3c1dd7169d5d0e17b77b8b4a6088fe122c74a6942dc42989ae44a4cf6edfe2bb0ee4f5a6d59dab
7
+ data.tar.gz: d98356701a491e17c6beea0abeedf0530515f13f6952bb3278d289089990a87b984fbf64bcf3e91671f7cc2658acca1f3737eb1609f31078ab0239ec52c53266
data/.rubocop.yml CHANGED
@@ -42,14 +42,7 @@ LineLength:
42
42
 
43
43
  MethodLength:
44
44
  Description: 'Avoid methods longer than 10 lines of code.'
45
- Max: 27 # 85
46
-
47
- CyclomaticComplexity:
48
- Description: 'Avoid complex methods.'
49
- Max: 9
50
-
51
- PerceivedComplexity:
52
- Max: 11 # 17
45
+ Max: 18 # 27 # 85
53
46
 
54
47
  AbcSize:
55
- Max: 48 # 62
48
+ Max: 23 # 62
data/lib/foreplay.rb CHANGED
@@ -5,6 +5,7 @@ require 'foreplay/engine'
5
5
  require 'foreplay/engine/remote'
6
6
  require 'foreplay/engine/remote/check'
7
7
  require 'foreplay/engine/remote/step'
8
+ require 'foreplay/engine/port'
8
9
  require 'foreplay/engine/role'
9
10
  require 'foreplay/engine/secrets'
10
11
  require 'foreplay/engine/server'
@@ -1,6 +1,6 @@
1
1
  require 'yaml'
2
2
  require 'string'
3
- require 'active_support/core_ext/object'
3
+ require 'hash'
4
4
 
5
5
  class Foreplay::Engine
6
6
  include Foreplay
@@ -29,49 +29,19 @@ class Foreplay::Engine
29
29
  puts "#{mode.capitalize}ing #{environment.dup.yellow} environment, "\
30
30
  "#{explanatory_text(filters, 'role')}, #{explanatory_text(filters, 'server')}"
31
31
 
32
- threads = []
33
-
34
- roles.each do |role, additional_instructions|
35
- next if role == DEFAULTS_KEY # 'defaults' is not a role
36
- next if filters.key?('role') && filters['role'] != role
37
-
38
- threads.concat Foreplay::Engine::Role.new(
32
+ actionable_roles.map do |role, instructions|
33
+ Foreplay::Engine::Role.new(
39
34
  environment,
40
35
  mode,
41
- build_instructions(role, additional_instructions)
36
+ build_instructions(role, instructions)
42
37
  ).threads
43
- end
44
-
45
- threads.each(&:join)
38
+ end.flatten.each(&:join)
46
39
 
47
40
  puts mode == :deploy ? 'Finished deployment' : 'Deployment configuration check was successful'
48
41
  end
49
42
 
50
- # Returns a new hash with +hash+ and +other_hash+ merged recursively, including arrays.
51
- #
52
- # h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
53
- # h2 = { x: { y: [7,8,9] }, z: 'xyz' }
54
- # h1.supermerge(h2)
55
- # #=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
56
- def supermerge(hash, other_hash)
57
- fail 'supermerge only works if you pass two hashes. '\
58
- "You passed a #{hash.class} and a #{other_hash.class}." unless hash.is_a?(Hash) && other_hash.is_a?(Hash)
59
-
60
- new_hash = hash.deep_dup
61
-
62
- other_hash.each_pair do |k, v|
63
- tv = new_hash[k]
64
-
65
- if tv.is_a?(Hash) && v.is_a?(Hash)
66
- new_hash[k] = supermerge(tv, v)
67
- elsif tv.is_a?(Array) || v.is_a?(Array)
68
- new_hash[k] = Array.wrap(tv) + Array.wrap(v)
69
- else
70
- new_hash[k] = v
71
- end
72
- end
73
-
74
- new_hash
43
+ def actionable_roles
44
+ roles.select { |role, _i| role != DEFAULTS_KEY && role != filters['role'] }
75
45
  end
76
46
 
77
47
  private
@@ -81,7 +51,7 @@ class Foreplay::Engine
81
51
  end
82
52
 
83
53
  def build_instructions(role, additional_instructions)
84
- instructions = supermerge(defaults, additional_instructions)
54
+ instructions = defaults.supermerge(additional_instructions)
85
55
  instructions['role'] = role
86
56
  required_keys = %w(name environment role servers path repository)
87
57
 
@@ -115,16 +85,19 @@ class Foreplay::Engine
115
85
  'port' => 50_000
116
86
  }
117
87
 
118
- # Add secret environment variables
119
- secrets = Foreplay::Engine::Secrets.new(environment, roles_all['secrets']).fetch || {}
120
- @defaults['env'] = @defaults['env'].merge secrets
88
+ @defaults['env'].merge! secrets
121
89
  @defaults['application'] = secrets
122
90
 
123
- @defaults = supermerge(@defaults, roles_all[DEFAULTS_KEY]) if roles_all.key? DEFAULTS_KEY
124
- @defaults = supermerge(@defaults, roles[DEFAULTS_KEY]) if roles.key? DEFAULTS_KEY
91
+ @defaults = @defaults.supermerge(roles_all[DEFAULTS_KEY]) if roles_all.key? DEFAULTS_KEY
92
+ @defaults = @defaults.supermerge(roles[DEFAULTS_KEY]) if roles.key? DEFAULTS_KEY
125
93
  @defaults
126
94
  end
127
95
 
96
+ # Secret environment variables
97
+ def secrets
98
+ @secrets ||= Foreplay::Engine::Secrets.new(environment, roles_all['secrets']).fetch || {}
99
+ end
100
+
128
101
  def roles
129
102
  @roles ||= roles_all[environment]
130
103
  end
@@ -0,0 +1,66 @@
1
+ module Foreplay::Engine::Port
2
+ include Foreplay
3
+
4
+ def host
5
+ return @host if @host
6
+ @host, _p = server.split(':') # Parse host + port
7
+ @host
8
+ end
9
+
10
+ def name
11
+ @name ||= instructions['name']
12
+ end
13
+
14
+ def current_port
15
+ @current_port ||= port_details['current_port']
16
+ end
17
+
18
+ def current_service
19
+ @current_service ||= port_details['current_service']
20
+ end
21
+
22
+ def former_port
23
+ @former_port ||= port_details['former_port']
24
+ end
25
+
26
+ def former_service
27
+ @former_service ||= port_details['former_service']
28
+ end
29
+
30
+ def current_port_file
31
+ @current_port_file ||= ".foreplay/#{name}/current_port"
32
+ end
33
+
34
+ def port_steps
35
+ @port_steps ||= [
36
+ {
37
+ 'command' => "mkdir -p .foreplay/#{name} && touch #{current_port_file} && cat #{current_port_file}",
38
+ 'silent' => true
39
+ }
40
+ ]
41
+ end
42
+
43
+ def port_details
44
+ return @port_details if @port_details
45
+
46
+ current_port_string = Foreplay::Engine::Remote.new(server, port_steps, instructions).__send__(mode).strip!
47
+
48
+ if current_port_string.blank?
49
+ puts "#{host}#{INDENT}No instance is currently deployed"
50
+ else
51
+ puts "#{host}#{INDENT}Current instance is using port #{current_port_string}"
52
+ end
53
+
54
+ cp = current_port_string.to_i
55
+ port = instructions['port']
56
+ ports = [port + 1000, port]
57
+ cp, fp = cp == port ? ports : ports.reverse
58
+
59
+ @port_details = {
60
+ 'current_port' => cp,
61
+ 'current_service' => "#{name}-#{cp}",
62
+ 'former_port' => fp,
63
+ 'former_service' => "#{name}-#{fp}"
64
+ }
65
+ end
66
+ end
@@ -22,7 +22,7 @@ class Foreplay::Engine::Remote
22
22
  puts "#{host}#{INDENT}Successfully connected to #{host} on port #{port}"
23
23
 
24
24
  session.shell do |sh|
25
- steps.each { |step| output += Foreplay::Engine::Remote::Step.new(host, sh, step, instructions).deploy }
25
+ steps.each { |step| output += Foreplay::Engine::Remote::Step.new(host, sh, step, instructions).execute }
26
26
  end
27
27
 
28
28
  session.close
@@ -9,31 +9,22 @@ class Foreplay::Engine::Remote::Step
9
9
  @instructions = i
10
10
  end
11
11
 
12
- def deploy
12
+ def execute
13
13
  puts "#{host}#{INDENT}#{(step['commentary'] || step['command']).yellow}" unless step['silent'] == true
14
+ output Foreplay::Engine::Step.new(step, instructions).build.map { |command| execute_command(command) }.join
15
+ end
14
16
 
15
- # Output from this step
16
- output = ''
17
- previous = '' # We don't need or want the final CRLF
18
- commands = Foreplay::Engine::Step.new(step, instructions).build
19
-
20
- commands.each do |command|
21
- process = shell.execute command
22
-
23
- process.on_output do |_, o|
24
- previous = o
25
- output += previous
26
- end
27
-
28
- shell.wait!
29
-
30
- if step['ignore_error'] == true || process.exit_status == 0
31
- print output.gsub!(/^/, "#{host}#{INDENT * 2}") unless step['silent'] == true || output.blank?
32
- else
33
- terminate(output)
34
- end
35
- end
17
+ def execute_command(command)
18
+ o = ''
19
+ process = shell.execute command
20
+ process.on_output { |_, po| o = po }
21
+ shell.wait!
22
+ terminate(o) unless step['ignore_error'] == true || process.exit_status == 0
23
+ o
24
+ end
36
25
 
37
- output
26
+ def output(o)
27
+ puts o.gsub!(/^/, "#{host}#{INDENT * 2}") unless step['silent'] == true || o.blank?
28
+ o
38
29
  end
39
30
  end
@@ -1,5 +1,5 @@
1
1
  class Foreplay::Engine::Server
2
- include Foreplay
2
+ include Foreplay::Engine::Port
3
3
  attr_reader :environment, :mode, :instructions, :server
4
4
 
5
5
  def initialize(e, m, i, s)
@@ -10,24 +10,33 @@ class Foreplay::Engine::Server
10
10
  end
11
11
 
12
12
  def execute
13
- preposition = mode == :deploy ? 'to' : 'for'
14
-
15
- message = "#{mode.capitalize}ing #{name.yellow} #{preposition} #{host.yellow} "
16
- message += "for the #{role.dup.yellow} role in the #{environment.dup.yellow} environment"
17
- puts message
13
+ execute_announce
14
+ foreman
15
+ env
16
+ Foreplay::Engine::Remote.new(server, steps, instructions).__send__ mode
17
+ end
18
18
 
19
- # Contents of .foreman file
20
- instructions['foreman']['app'] = current_service
21
- instructions['foreman']['port'] = current_port
22
- instructions['foreman']['user'] = user
23
- instructions['foreman']['log'] = "$HOME/#{path}/#{current_port}/log"
19
+ def execute_announce
20
+ preposition = mode == :deploy ? 'to' : 'for'
21
+ puts "#{mode.capitalize}ing #{name.yellow} #{preposition} #{host.yellow} "\
22
+ "for the #{role.dup.yellow} role in the #{environment.dup.yellow} environment"
23
+ end
24
24
 
25
- # Contents of .env file
26
- instructions['env']['HOME'] = '$HOME'
27
- instructions['env']['SHELL'] = '$SHELL'
28
- instructions['env']['PATH'] = '$PATH:`which bundle`'
25
+ def foreman
26
+ instructions['foreman'].merge!(
27
+ 'app' => current_service,
28
+ 'port' => current_port,
29
+ 'user' => user,
30
+ 'log' => "$HOME/#{path}/#{current_port}/log"
31
+ )
32
+ end
29
33
 
30
- Foreplay::Engine::Remote.new(server, steps, instructions).__send__ mode
34
+ def env
35
+ instructions['env'].merge!(
36
+ 'HOME' => '$HOME',
37
+ 'SHELL' => '$SHELL',
38
+ 'PATH' => '$PATH:`which bundle`'
39
+ )
31
40
  end
32
41
 
33
42
  def role
@@ -38,10 +47,6 @@ class Foreplay::Engine::Server
38
47
  @user ||= instructions['user']
39
48
  end
40
49
 
41
- def name
42
- @name ||= instructions['name']
43
- end
44
-
45
50
  def path
46
51
  return @path if @path
47
52
 
@@ -51,12 +56,6 @@ class Foreplay::Engine::Server
51
56
  @path
52
57
  end
53
58
 
54
- def host
55
- return @host if @host
56
- @host, _p = server.split(':') # Parse host + port
57
- @host
58
- end
59
-
60
59
  def steps
61
60
  @steps ||= YAML.load(
62
61
  ERB.new(
@@ -66,57 +65,4 @@ class Foreplay::Engine::Server
66
65
  ).result(binding)
67
66
  )
68
67
  end
69
-
70
- def current_port
71
- @current_port ||= port_details['current_port']
72
- end
73
-
74
- def current_service
75
- @current_service ||= port_details['current_service']
76
- end
77
-
78
- def former_port
79
- @former_port ||= port_details['former_port']
80
- end
81
-
82
- def former_service
83
- @former_service ||= port_details['former_service']
84
- end
85
-
86
- def current_port_file
87
- @current_port_file ||= ".foreplay/#{name}/current_port"
88
- end
89
-
90
- def port_steps
91
- @port_steps ||= [
92
- {
93
- 'command' => "mkdir -p .foreplay/#{name} && touch #{current_port_file} && cat #{current_port_file}",
94
- 'silent' => true
95
- }
96
- ]
97
- end
98
-
99
- def port_details
100
- return @port_details if @port_details
101
-
102
- current_port_string = Foreplay::Engine::Remote.new(server, port_steps, instructions).__send__(mode).strip!
103
-
104
- if current_port_string.blank?
105
- puts "#{host}#{INDENT}No instance is currently deployed"
106
- else
107
- puts "#{host}#{INDENT}Current instance is using port #{current_port_string}"
108
- end
109
-
110
- cp = current_port_string.to_i
111
- port = instructions['port']
112
- ports = [port + 1000, port]
113
- cp, fp = cp == port ? ports : ports.reverse
114
-
115
- @port_details = {
116
- 'current_port' => cp,
117
- 'current_service' => "#{name}-#{cp}",
118
- 'former_port' => fp,
119
- 'former_service' => "#{name}-#{fp}"
120
- }
121
- end
122
68
  end
@@ -9,44 +9,90 @@ class Foreplay::Engine::Step
9
9
  def build
10
10
  # Each step can be (1) a command or (2) a series of values to add to a file
11
11
  if step.key?('key')
12
- instructions.key?(step['key']) ? build_commands(step, instructions) : []
12
+ instructions.key?(step['key']) ? commands : []
13
13
  else
14
14
  # ...or just execute the command specified
15
15
  [step['command']]
16
16
  end
17
17
  end
18
18
 
19
- def build_commands(step, instructions)
20
- # Add values from the config file to a file on the remote machine
21
- key = step['key']
22
- prefix = step['prefix'] || ''
23
- suffix = step['suffix'] || ''
24
- path = step['path'] || ''
25
- before = step['before'] || ''
26
- delimiter = step['delimiter'] || ''
27
- after = step['after'] || ''
19
+ def commands
20
+ return @commands if @commands
28
21
 
29
22
  step['silent'] = true
30
- filename = "#{path}#{prefix}#{key}#{suffix}"
31
23
 
32
- if step.key?('header')
33
- commands = ["echo \"#{step['header']}\" > #{filename}"]
34
- redirect = '>>'
24
+ if header?
25
+ @commands = ["echo \"#{header}\" > #{filename}"]
26
+ redirect
35
27
  else
36
- commands = []
37
- redirect = '>'
28
+ @commands = []
38
29
  end
39
30
 
40
31
  if instructions[key].is_a? Hash
41
- instructions[key].each do |k, v|
42
- commands << "echo \"#{before}#{k}#{delimiter}#{v}#{after}\" #{redirect} #{filename}"
43
- redirect = '>>'
44
- end
32
+ build_commands_from_hash
45
33
  else
46
- commands << "echo \"#{before}#{delimiter}#{instructions[key]}#{after}\" #{redirect} #{filename}"
47
- redirect = '>>'
34
+ build_commands_from_string
48
35
  end
49
36
 
50
- commands
37
+ @commands
38
+ end
39
+
40
+ def build_commands_from_hash
41
+ instructions[key].each do |k, v|
42
+ @commands << "echo \"#{before}#{k}#{delimiter}#{v}#{after}\" #{redirect} #{filename}"
43
+ end
44
+ end
45
+
46
+ def build_commands_from_string
47
+ @commands << "echo \"#{before}#{delimiter}#{instructions[key]}#{after}\" #{redirect} #{filename}"
48
+ end
49
+
50
+ def redirect
51
+ if @redirect
52
+ '>>'
53
+ else
54
+ @redirect = true
55
+ '>'
56
+ end
57
+ end
58
+
59
+ def filename
60
+ @filename ||= "#{path}#{prefix}#{key}#{suffix}"
61
+ end
62
+
63
+ def key
64
+ @key ||= step['key']
65
+ end
66
+
67
+ def prefix
68
+ @prefix ||= step['prefix'] || ''
69
+ end
70
+
71
+ def suffix
72
+ @suffix ||= step['suffix'] || ''
73
+ end
74
+
75
+ def path
76
+ @path ||= step['path'] || ''
77
+ end
78
+
79
+ def before
80
+ @before ||= step['before'] || ''
81
+ end
82
+
83
+ def delimiter
84
+ @delimiter ||= step['delimiter'] || ''
85
+ end
86
+
87
+ def after
88
+ @after ||= step['after'] || ''
89
+ end
90
+
91
+ def header
92
+ @header ||= step['header']
93
+ end
94
+
95
+ def header?
96
+ header.present?
51
97
  end
52
98
  end
@@ -1,3 +1,3 @@
1
1
  module Foreplay
2
- VERSION = '0.9.8'
2
+ VERSION = '0.9.9'
3
3
  end
data/lib/hash.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'active_support/core_ext/object'
2
+
3
+ class Hash
4
+ # Returns a new hash with +hash+ and +other_hash+ merged recursively, including arrays.
5
+ #
6
+ # h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
7
+ # h2 = { x: { y: [7,8,9] }, z: 'xyz' }
8
+ # h1.supermerge(h2)
9
+ # #=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
10
+ def supermerge(other_hash)
11
+ fail 'supermerge only works if you pass a hash. '\
12
+ "You passed a #{self.class} and a #{other_hash.class}." unless other_hash.is_a?(Hash)
13
+
14
+ new_hash = deep_dup
15
+
16
+ other_hash.each_pair do |k, v|
17
+ tv = new_hash[k]
18
+
19
+ if tv.is_a?(Hash) && v.is_a?(Hash)
20
+ new_hash[k] = tv.supermerge(v)
21
+ elsif tv.is_a?(Array) || v.is_a?(Array)
22
+ new_hash[k] = Array.wrap(tv) + Array.wrap(v)
23
+ else
24
+ new_hash[k] = v
25
+ end
26
+ end
27
+
28
+ new_hash
29
+ end
30
+ end
@@ -24,7 +24,7 @@ describe Foreplay::Launcher do
24
24
  allow(session).to receive(:shell).and_yield(shell)
25
25
  allow(shell).to receive(:execute).and_return(process)
26
26
  allow(shell).to receive(:wait!).and_return(false)
27
- allow(process).to receive(:on_output).and_yield(process, "output message\n")
27
+ allow(process).to receive(:on_output).and_yield(process, "output message 1\noutput message 2\n")
28
28
  allow(process).to receive(:exit_status).and_return(0)
29
29
  end
30
30
 
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'hash'
3
+
4
+ describe Hash do
5
+ context '#supermerge' do
6
+ it 'should complain unless two hashes are passed to it' do
7
+ expect { {}.supermerge('y') }.to raise_error(RuntimeError)
8
+ end
9
+
10
+ it 'should merge two simple hashes' do
11
+ expect({ a: 'x' }.supermerge(b: 'y')).to eq(a: 'x', b: 'y')
12
+ end
13
+
14
+ it 'should merge two hashes both with arrays at the same key' do
15
+ expect({ a: ['x'] }.supermerge(a: ['y'])).to eq(a: %w(x y))
16
+ end
17
+
18
+ it 'should merge an array and a value at the same key' do
19
+ expect({ a: 'x' }.supermerge(a: ['y'])).to eq(a: %w(x y))
20
+ end
21
+
22
+ it 'should replace a value at the same key' do
23
+ expect({ a: 'x' }.supermerge(a: 'y')).to eq(a: 'y')
24
+ end
25
+
26
+ it 'should merge two subhashes at the same key' do
27
+ expect({ a: { b: 'x' } }.supermerge(a: { c: 'y' })).to eq(a: { b: 'x', c: 'y' })
28
+ end
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreplay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xenapto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-06 00:00:00.000000000 Z
11
+ date: 2015-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foreman
@@ -222,6 +222,7 @@ files:
222
222
  - lib/foreplay.rb
223
223
  - lib/foreplay/cli.rb
224
224
  - lib/foreplay/engine.rb
225
+ - lib/foreplay/engine/port.rb
225
226
  - lib/foreplay/engine/remote.rb
226
227
  - lib/foreplay/engine/remote/check.rb
227
228
  - lib/foreplay/engine/remote/step.rb
@@ -235,11 +236,12 @@ files:
235
236
  - lib/foreplay/setup.rb
236
237
  - lib/foreplay/setup/foreplay.yml
237
238
  - lib/foreplay/version.rb
239
+ - lib/hash.rb
238
240
  - lib/string.rb
239
241
  - spec/lib/foreplay/deploy_spec.rb
240
- - spec/lib/foreplay/engine_spec.rb
241
242
  - spec/lib/foreplay/secrets_spec.rb
242
243
  - spec/lib/foreplay/setup_spec.rb
244
+ - spec/lib/hash_spec.rb
243
245
  - spec/spec_helper.rb
244
246
  homepage: https://github.com/Xenapto/foreplay
245
247
  licenses:
@@ -271,7 +273,7 @@ test_files:
271
273
  - features/setup.feature
272
274
  - features/support/env.rb
273
275
  - spec/lib/foreplay/deploy_spec.rb
274
- - spec/lib/foreplay/engine_spec.rb
275
276
  - spec/lib/foreplay/secrets_spec.rb
276
277
  - spec/lib/foreplay/setup_spec.rb
278
+ - spec/lib/hash_spec.rb
277
279
  - spec/spec_helper.rb
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
- require 'foreplay'
3
-
4
- describe Foreplay::Engine do
5
- context '#supermerge' do
6
- let(:engine) { Foreplay::Engine.new('b', 'b') }
7
-
8
- it 'should complain unless two hashes are passed to it' do
9
- expect { engine.supermerge('x', 'y') }.to raise_error(RuntimeError)
10
- end
11
-
12
- it 'should merge two simple hashes' do
13
- expect(engine.supermerge({ a: 'x' }, b: 'y')).to eq(a: 'x', b: 'y')
14
- end
15
-
16
- it 'should merge two hashes both with arrays at the same key' do
17
- expect(engine.supermerge({ a: ['x'] }, a: ['y'])).to eq(a: %w(x y))
18
- end
19
-
20
- it 'should merge an array and a value at the same key' do
21
- expect(engine.supermerge({ a: 'x' }, a: ['y'])).to eq(a: %w(x y))
22
- end
23
-
24
- it 'should replace a value at the same key' do
25
- expect(engine.supermerge({ a: 'x' }, a: 'y')).to eq(a: 'y')
26
- end
27
-
28
- it 'should merge two subhashes at the same key' do
29
- expect(engine.supermerge({ a: { b: 'x' } }, a: { c: 'y' })).to eq(a: { b: 'x', c: 'y' })
30
- end
31
- end
32
- end