db-clone 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +21 -0
  5. data/app/assets/javascripts/db_sync/application.js +13 -0
  6. data/app/assets/stylesheets/db_sync/application.css +15 -0
  7. data/app/controllers/db_sync/application_controller.rb +5 -0
  8. data/app/helpers/db_sync/application_helper.rb +4 -0
  9. data/app/views/layouts/db_sync/application.html.erb +14 -0
  10. data/config/routes.rb +2 -0
  11. data/lib/db_sync.rb +27 -0
  12. data/lib/db_sync/cmd_builder.rb +58 -0
  13. data/lib/db_sync/db_selections.rb +65 -0
  14. data/lib/db_sync/engine.rb +12 -0
  15. data/lib/db_sync/version.rb +3 -0
  16. data/lib/tasks/db_sync_tasks.rake +6 -0
  17. data/spec/cmd_builder_spec.rb +73 -0
  18. data/spec/db_selections_spec.rb +74 -0
  19. data/spec/db_sync_spec.rb +15 -0
  20. data/spec/dummy/README.rdoc +28 -0
  21. data/spec/dummy/Rakefile +6 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  26. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  27. data/spec/dummy/bin/bundle +3 -0
  28. data/spec/dummy/bin/rails +4 -0
  29. data/spec/dummy/bin/rake +4 -0
  30. data/spec/dummy/bin/setup +29 -0
  31. data/spec/dummy/config.ru +4 -0
  32. data/spec/dummy/config/application.rb +32 -0
  33. data/spec/dummy/config/boot.rb +5 -0
  34. data/spec/dummy/config/database.yml +59 -0
  35. data/spec/dummy/config/environment.rb +5 -0
  36. data/spec/dummy/config/environments/development.rb +41 -0
  37. data/spec/dummy/config/environments/production.rb +79 -0
  38. data/spec/dummy/config/environments/test.rb +42 -0
  39. data/spec/dummy/config/initializers/assets.rb +11 -0
  40. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  42. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  43. data/spec/dummy/config/initializers/inflections.rb +16 -0
  44. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  45. data/spec/dummy/config/initializers/session_store.rb +3 -0
  46. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/spec/dummy/config/locales/en.yml +23 -0
  48. data/spec/dummy/config/routes.rb +4 -0
  49. data/spec/dummy/config/secrets.yml +22 -0
  50. data/spec/dummy/db/test.sqlite3 +0 -0
  51. data/spec/dummy/log/development.log +0 -0
  52. data/spec/dummy/log/test.log +40 -0
  53. data/spec/dummy/public/404.html +67 -0
  54. data/spec/dummy/public/422.html +67 -0
  55. data/spec/dummy/public/500.html +66 -0
  56. data/spec/dummy/public/favicon.ico +0 -0
  57. data/spec/rails_helper.rb +59 -0
  58. data/spec/spec_helper.rb +92 -0
  59. metadata +214 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1ab0818f5cf4ec50e0e763f3ec4aba7fed545fa
4
+ data.tar.gz: 62d920d4cab87adde594c102329469209dc82ed9
5
+ SHA512:
6
+ metadata.gz: c26ba96324376ce1ce7609643116df1ad2ea6484ba42fd61e085a734b5f8748af0c858ffddb33c08865d463d1ebea2f5e3f0997264cbde6e0ceebbd58de9a03d
7
+ data.tar.gz: 3d12bba1f9f407419c68a11e3b9f315cdc1fa7e51515646c3a2a5556c94f81d810426915606e63d7cf4985e747246932656d82be9dc787bdb5c69f4edeb0a136
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Sean Huber
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = DbSync
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
9
+ load 'rails/tasks/engine.rake'
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
14
+
15
+ require 'rspec/core'
16
+ require 'rspec/core/rake_task'
17
+
18
+ desc 'Run all specs in spec directory (excluding plugin specs)'
19
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
20
+
21
+ task default: :spec
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ module DbSync
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module DbSync
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>DbSync</title>
5
+ <%= stylesheet_link_tag "db_sync/application", media: "all" %>
6
+ <%= javascript_include_tag "db_sync/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ DbSync::Engine.routes.draw do
2
+ end
data/lib/db_sync.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'colorize'
2
+ require 'db_sync/cmd_builder'
3
+ require 'db_sync/db_selections'
4
+ require 'db_sync/engine'
5
+
6
+ module DbSync
7
+ mattr_accessor :config
8
+
9
+ def self.sync!( **opts )
10
+ DbSync.config ||= {}
11
+ DbSync.config[:ignore_tables] ||= []
12
+ DbSync.config[:default_source] ||= 'production'
13
+ DbSync.config[:default_destination] ||= 'development'
14
+
15
+ ds = DbSelections.new Rails.root.join('config', 'database.yml')
16
+ src_dest = if opts[:manual]
17
+ [:source_prompt, :source_get, :dest_prompt, :dest_get].each{|m| ds.send(m)}
18
+ ds.selections
19
+ else
20
+ ds.selections( use_defaults: true )
21
+ end
22
+
23
+ cb = CmdBuilder.new src_dest
24
+ puts "\n Executing: #{cb.get_cmd.light_blue}\n\n"
25
+ cb.exec!
26
+ end
27
+ end
@@ -0,0 +1,58 @@
1
+ module DbSync
2
+ class CmdBuilder
3
+ VALID_DB_KEYS = ['host', 'port', 'username', 'database', 'password']
4
+ SUPPORTED_DBS = [:mysql, :postgresql]
5
+
6
+ def exec!() exec @cmd end
7
+
8
+ def initialize( selections )
9
+ raise(ArgumentError, 'Both source and destination must be set') unless selections[:src] && selections[:dest]
10
+ raise(ArgumentError, 'Source and destination databases must be of the same type') unless selections[:src]['adapter'] == selections[:dest]['adapter']
11
+ SUPPORTED_DBS.each{|db| @db_type = db if selections[:src]['adapter'].include?(db.to_s)}
12
+ raise(ArgumentError, "Unsupported database: #{selections[:src]['adapter']}") unless @db_type
13
+ src_dest = selections.map{|k,v| [k,v.delete_if{|i,j| !VALID_DB_KEYS.include?(i)}]}.to_h
14
+ @cmd = send("build_#{@db_type}_cmd", src_dest)
15
+ end
16
+
17
+ def get_cmd() @cmd end
18
+
19
+ private
20
+
21
+ def build_mysql_cmd( src_dest )
22
+ mysqldump_args = [
23
+ "mysqldump --no-create-db --add-drop-table --lock-tables=false",
24
+ "--user=#{src_dest[:src]['username']}",
25
+ "--password=#{src_dest[:src]['password']}",
26
+ "--host=#{src_dest[:src]['host']}",
27
+ "--port=#{src_dest[:src]['port']}"
28
+ ]
29
+
30
+ DbSync.config[:ignore_tables].each{|tbl| mysqldump_args << "--ignore-table=#{src_dest[:dest]['database']}.#{tbl}"} if DbSync.config && DbSync.config[:ignore_tables].is_a?(Array)
31
+
32
+ (mysqldump_args + [
33
+ "#{src_dest[:src]['database']}",
34
+ "| mysql",
35
+ "--user=#{src_dest[:dest]['username']}",
36
+ "--password=#{src_dest[:dest]['password']}",
37
+ "--host=#{src_dest[:dest]['host']}",
38
+ "--port=#{src_dest[:dest]['port']}",
39
+ "#{src_dest[:dest]['database']}"
40
+ ]).join(' ')
41
+ end
42
+
43
+ def build_postgresql_cmd( src_dest )
44
+ [
45
+ "pg_dump --no-password --clean",
46
+ "--host=#{src_dest[:src]['host']}",
47
+ "--port=#{src_dest[:src]['port']}",
48
+ "--username=#{src_dest[:src]['username']}",
49
+ "#{src_dest[:src]['database']}",
50
+ "| psql",
51
+ "--host=#{src_dest[:dest]['host']}",
52
+ "--port=#{src_dest[:dest]['port']}",
53
+ "--username=#{src_dest[:dest]['username']}",
54
+ "#{src_dest[:dest]['database']}"
55
+ ].join(' ')
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ require 'yaml'
2
+
3
+ module DbSync
4
+ class DbSelections
5
+ # read database blocks from config/database.yml
6
+ def initialize( database_yml )
7
+ h = YAML.load_file database_yml
8
+ @dbs = h.sort_by{|k,v| k}.map{|k,v| v.merge(label: k)}
9
+ @default_src_idx = @dbs.find_index{|db| db[:label] == DbSync.config[:default_source]}
10
+ @default_dest_idx = @dbs.find_index{|db| db[:label] == DbSync.config[:default_destination]}
11
+ @selections = {src: nil, dest: nil}
12
+ end
13
+
14
+ # STEP 1: prompt user for which database block to use as the source
15
+ def source_prompt
16
+ db_prompt 'source'
17
+ end
18
+
19
+ # STEP 2: retrieve from use which database block to use as the source
20
+ def source_get
21
+ db_select 'source'
22
+ end
23
+
24
+ # STEP 3: prompt user for which database block to use as the destination
25
+ def dest_prompt
26
+ db_prompt 'destination'
27
+ end
28
+
29
+ # STEP 4: retrieve from use which database block to use as the destination
30
+ def dest_get
31
+ db_select 'destination'
32
+ end
33
+
34
+ def selections( **opts )
35
+ opts[:use_defaults] ? {src: @dbs[@default_src_idx], dest: @dbs[@default_dest_idx]} : @selections.map{|k,v| [k, v.nil? ? nil : @dbs[v]] }.to_h
36
+ end
37
+
38
+ private
39
+
40
+ def db_prompt( src_dest )
41
+ num_dbs = @dbs.length
42
+ puts "\n Choose a #{src_dest.magenta} database from one of the blocks defined in #{'config/database.yml'.light_green}:\n\n"
43
+ @dbs.each_with_index do |db, idx|
44
+ if src_dest == 'destination' && idx == @selections[:src]
45
+ puts " [ #{"#{'X'.ljust(num_dbs.to_s.length).red}"} ] #{db[:label].red}"
46
+ else
47
+ puts " [ #{"#{(idx+1).to_s.ljust(num_dbs.to_s.length).light_blue}"} ] #{db[:label].yellow}"
48
+ end
49
+ end
50
+ default = src_dest=='source' ? "#{@dbs[@default_src_idx][:label]} = #{(@default_src_idx+1).to_s.light_blue}" : "#{@dbs[@default_dest_idx][:label]} = #{(@default_dest_idx+1).to_s.light_blue}"
51
+ print "\n Choose a #{src_dest.magenta} database (#{'1'.light_blue}-#{num_dbs.to_s.light_blue}) [#{default}]: "
52
+ end
53
+
54
+ def db_select( src_dest )
55
+ sk = src_dest=='source' ? :src : :dest
56
+ idx = STDIN.gets.chomp
57
+ idx = ((src_dest=='source' ? @default_src_idx : @default_dest_idx)+1).to_s if idx == ''
58
+ raise(ArgumentError, "Invalid selection: #{src_idx}") unless (1..@dbs.length).map(&:to_s).include?(idx)
59
+ @selections[sk] = idx.to_i - 1
60
+ raise(ArgumentError, 'Destination cannot be the same as the source') unless @selections.values.uniq.length == 2
61
+ raise(ArgumentError, 'Source and destination databases must be of the same type') if src_dest=='destination' && @dbs[@selections[:src]]['adapter'] != @dbs[@selections[:dest]]['adapter']
62
+ puts "\n #{src_dest.capitalize.magenta} set to: #{@dbs[@selections[sk]][:label].yellow}"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,12 @@
1
+ module DbSync
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace DbSync
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec, :fixture => false
7
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
8
+ g.assets false
9
+ g.helper false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module DbSync
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,6 @@
1
+ namespace :db do
2
+ desc 'syncs a source database to a destination database'
3
+ task :sync, [:manual] => :environment do |t, args|
4
+ DbSync.sync! manual: args[:manual].present?
5
+ end
6
+ end
@@ -0,0 +1,73 @@
1
+ require 'rails_helper'
2
+
3
+ module DbSync
4
+ describe CmdBuilder do
5
+ describe 'postgresql command builder' do
6
+ h = {
7
+ src: {
8
+ 'adapter' => 'postgresql',
9
+ 'encoding' => 'unicode',
10
+ 'database' => 'other_postgresql_db',
11
+ 'username' => 'other_postgresql_user',
12
+ 'password' => 'other_postgresql_password',
13
+ 'host' => 'fake_postgresql_host',
14
+ 'port' => 5432,
15
+ :label => 'second_test_postgresql'
16
+ },
17
+ dest: {
18
+ 'adapter' => 'postgresql',
19
+ 'encoding' => 'unicode',
20
+ 'database' => 'fake_postgresql_db',
21
+ 'username' => 'fake_postgresql_user',
22
+ 'password' => 'fake_postgresql_password',
23
+ 'host' => 'fake_postgresql_host',
24
+ 'port' => 5432,
25
+ :label => 'test_postgresql'
26
+ }
27
+ }
28
+ cb = CmdBuilder.new h
29
+
30
+ it 'should be able to generate a pg_dump command' do
31
+ expect(cb.get_cmd).to eql("pg_dump --no-password --clean --host=fake_postgresql_host --port=5432 --username=other_postgresql_user other_postgresql_db | psql --host=fake_postgresql_host --port=5432 --username=fake_postgresql_user fake_postgresql_db")
32
+ end
33
+ end
34
+
35
+ describe 'mysql command builder' do
36
+ before(:each) do
37
+ @h = {
38
+ :src => {
39
+ 'adapter' => 'mysql2',
40
+ 'database' => 'fake_mysql_db',
41
+ 'username' => 'fake_mysql_usr',
42
+ 'password' => 'fake_mysql_password',
43
+ 'host' => 'fake_mysql_host',
44
+ 'port' => 3306,
45
+ :label => 'test_mysql'
46
+ },
47
+ :dest => {
48
+ 'adapter' => 'mysql2',
49
+ 'database' => 'other_mysql_db',
50
+ 'username' => 'other_mysql_usr',
51
+ 'password' => 'other_mysql_password',
52
+ 'host' => 'other_mysql_host',
53
+ 'port' => 3306,
54
+ :label => 'second_test_mysql'
55
+ }
56
+ }
57
+ end
58
+
59
+ it 'should be able to generate a mysqldump command' do
60
+ cb = CmdBuilder.new @h
61
+ expect(cb.get_cmd).to eql("mysqldump --no-create-db --add-drop-table --lock-tables=false --user=fake_mysql_usr --password=fake_mysql_password --host=fake_mysql_host --port=3306 fake_mysql_db | mysql --user=other_mysql_usr --password=other_mysql_password --host=other_mysql_host --port=3306 other_mysql_db")
62
+ end
63
+
64
+ it 'should be able to generate a mysqldump command with ignore tables' do
65
+ DbSync.config = {
66
+ ignore_tables: ['tableAAAA', 'tableBBBB', 'tableCCCC']
67
+ }
68
+ cb = CmdBuilder.new @h
69
+ expect(cb.get_cmd).to eql("mysqldump --no-create-db --add-drop-table --lock-tables=false --user=fake_mysql_usr --password=fake_mysql_password --host=fake_mysql_host --port=3306 --ignore-table=other_mysql_db.tableAAAA --ignore-table=other_mysql_db.tableBBBB --ignore-table=other_mysql_db.tableCCCC fake_mysql_db | mysql --user=other_mysql_usr --password=other_mysql_password --host=other_mysql_host --port=3306 other_mysql_db")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,74 @@
1
+ require 'rails_helper'
2
+
3
+ module DbSync
4
+ describe DbSelections do
5
+ describe 'db selections' do
6
+ DbSync.config = {
7
+ default_source: 'production',
8
+ default_destination: 'development',
9
+ }
10
+ ds = DbSelections.new Rails.root.join('config', 'database.yml')
11
+
12
+ it 'should prompt for a source' do
13
+ str = "\n Choose a \e[0;35;49msource\e[0m database from one of the blocks defined in \e[0;92;49mconfig/database.yml\e[0m:\n\n [ \e[0;94;49m1\e[0m ] \e[0;33;49mdefault\e[0m\n [ \e[0;94;49m2\e[0m ] \e[0;33;49mdevelopment\e[0m\n [ \e[0;94;49m3\e[0m ] \e[0;33;49mproduction\e[0m\n [ \e[0;94;49m4\e[0m ] \e[0;33;49msecond_test_mysql\e[0m\n [ \e[0;94;49m5\e[0m ] \e[0;33;49msecond_test_postgresql\e[0m\n [ \e[0;94;49m6\e[0m ] \e[0;33;49mtest\e[0m\n [ \e[0;94;49m7\e[0m ] \e[0;33;49mtest_mysql\e[0m\n [ \e[0;94;49m8\e[0m ] \e[0;33;49mtest_postgresql\e[0m\n\n Choose a \e[0;35;49msource\e[0m database (\e[0;94;49m1\e[0m-\e[0;94;49m8\e[0m) [production = \e[0;94;49m3\e[0m]: "
14
+ expect { ds.source_prompt }.to output(str).to_stdout
15
+ end
16
+
17
+ it 'should set a source' do
18
+ allow(STDIN).to receive(:gets) { '5' }
19
+ str = "\n \e[0;35;49mSource\e[0m set to: \e[0;33;49msecond_test_postgresql\e[0m\n"
20
+ expect { ds.source_get }.to output(str).to_stdout
21
+ end
22
+
23
+ it 'should prompt for a destination' do
24
+ str = "\n Choose a \e[0;35;49mdestination\e[0m database from one of the blocks defined in \e[0;92;49mconfig/database.yml\e[0m:\n\n [ \e[0;94;49m1\e[0m ] \e[0;33;49mdefault\e[0m\n [ \e[0;94;49m2\e[0m ] \e[0;33;49mdevelopment\e[0m\n [ \e[0;94;49m3\e[0m ] \e[0;33;49mproduction\e[0m\n [ \e[0;94;49m4\e[0m ] \e[0;33;49msecond_test_mysql\e[0m\n [ \e[0;31;49mX\e[0m ] \e[0;31;49msecond_test_postgresql\e[0m\n [ \e[0;94;49m6\e[0m ] \e[0;33;49mtest\e[0m\n [ \e[0;94;49m7\e[0m ] \e[0;33;49mtest_mysql\e[0m\n [ \e[0;94;49m8\e[0m ] \e[0;33;49mtest_postgresql\e[0m\n\n Choose a \e[0;35;49mdestination\e[0m database (\e[0;94;49m1\e[0m-\e[0;94;49m8\e[0m) [development = \e[0;94;49m2\e[0m]: "
25
+ expect { ds.dest_prompt }.to output(str).to_stdout
26
+ end
27
+
28
+ it 'should set a destination' do
29
+ allow(STDIN).to receive(:gets) { '8' }
30
+ str = "\n \e[0;35;49mDestination\e[0m set to: \e[0;33;49mtest_postgresql\e[0m\n"
31
+ expect { ds.dest_get }.to output(str).to_stdout
32
+ end
33
+
34
+ it 'should have a source and destination set' do
35
+ expected_selections = {
36
+ src: {
37
+ 'adapter' => 'postgresql',
38
+ 'encoding' => 'unicode',
39
+ 'database' => 'other_postgresql_db',
40
+ 'username' => 'other_postgresql_user',
41
+ 'password' => 'other_postgresql_password',
42
+ 'host' => 'fake_postgresql_host',
43
+ 'port' => 5432,
44
+ :label => 'second_test_postgresql'
45
+ },
46
+ dest: {
47
+ 'adapter' => 'postgresql',
48
+ 'encoding' => 'unicode',
49
+ 'database' => 'fake_postgresql_db',
50
+ 'username' => 'fake_postgresql_user',
51
+ 'password' => 'fake_postgresql_password',
52
+ 'host' => 'fake_postgresql_host',
53
+ 'port' => 5432,
54
+ :label => 'test_postgresql'
55
+ }
56
+ }
57
+ expect(ds.selections).to eql(expected_selections)
58
+ end
59
+ end
60
+
61
+ describe 'db mismatched selections' do
62
+ ds = DbSelections.new Rails.root.join('config', 'database.yml')
63
+
64
+ it 'should prohibit syncing between different adapters' do
65
+ expect { ds.source_prompt }.to output.to_stdout
66
+ allow(STDIN).to receive(:gets) { '7' }
67
+ expect { ds.source_get }.to output.to_stdout
68
+ expect { ds.dest_prompt }.to output.to_stdout
69
+ allow(STDIN).to receive(:gets) { '8' }
70
+ expect { ds.dest_get }.to raise_error(ArgumentError)
71
+ end
72
+ end
73
+ end
74
+ end