foreplay 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
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