db-clone 1.0.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.
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