andyjeffries-rubyrep 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/History.txt +83 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +151 -0
  4. data/README.txt +37 -0
  5. data/bin/rubyrep +8 -0
  6. data/lib/rubyrep.rb +72 -0
  7. data/lib/rubyrep/base_runner.rb +195 -0
  8. data/lib/rubyrep/command_runner.rb +144 -0
  9. data/lib/rubyrep/committers/buffered_committer.rb +151 -0
  10. data/lib/rubyrep/committers/committers.rb +152 -0
  11. data/lib/rubyrep/configuration.rb +275 -0
  12. data/lib/rubyrep/connection_extenders/connection_extenders.rb +165 -0
  13. data/lib/rubyrep/connection_extenders/jdbc_extender.rb +65 -0
  14. data/lib/rubyrep/connection_extenders/mysql_extender.rb +59 -0
  15. data/lib/rubyrep/connection_extenders/postgresql_extender.rb +277 -0
  16. data/lib/rubyrep/database_proxy.rb +52 -0
  17. data/lib/rubyrep/direct_table_scan.rb +75 -0
  18. data/lib/rubyrep/generate_runner.rb +105 -0
  19. data/lib/rubyrep/initializer.rb +39 -0
  20. data/lib/rubyrep/log_helper.rb +30 -0
  21. data/lib/rubyrep/logged_change.rb +160 -0
  22. data/lib/rubyrep/logged_change_loader.rb +197 -0
  23. data/lib/rubyrep/noisy_connection.rb +80 -0
  24. data/lib/rubyrep/proxied_table_scan.rb +171 -0
  25. data/lib/rubyrep/proxy_block_cursor.rb +145 -0
  26. data/lib/rubyrep/proxy_connection.rb +431 -0
  27. data/lib/rubyrep/proxy_cursor.rb +44 -0
  28. data/lib/rubyrep/proxy_row_cursor.rb +43 -0
  29. data/lib/rubyrep/proxy_runner.rb +89 -0
  30. data/lib/rubyrep/replication_difference.rb +100 -0
  31. data/lib/rubyrep/replication_extenders/mysql_replication.rb +271 -0
  32. data/lib/rubyrep/replication_extenders/postgresql_replication.rb +236 -0
  33. data/lib/rubyrep/replication_extenders/replication_extenders.rb +26 -0
  34. data/lib/rubyrep/replication_helper.rb +142 -0
  35. data/lib/rubyrep/replication_initializer.rb +327 -0
  36. data/lib/rubyrep/replication_run.rb +142 -0
  37. data/lib/rubyrep/replication_runner.rb +166 -0
  38. data/lib/rubyrep/replicators/replicators.rb +42 -0
  39. data/lib/rubyrep/replicators/two_way_replicator.rb +361 -0
  40. data/lib/rubyrep/scan_progress_printers/progress_bar.rb +65 -0
  41. data/lib/rubyrep/scan_progress_printers/scan_progress_printers.rb +65 -0
  42. data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +111 -0
  43. data/lib/rubyrep/scan_report_printers/scan_report_printers.rb +67 -0
  44. data/lib/rubyrep/scan_report_printers/scan_summary_reporter.rb +75 -0
  45. data/lib/rubyrep/scan_runner.rb +25 -0
  46. data/lib/rubyrep/session.rb +230 -0
  47. data/lib/rubyrep/sync_helper.rb +121 -0
  48. data/lib/rubyrep/sync_runner.rb +31 -0
  49. data/lib/rubyrep/syncers/syncers.rb +112 -0
  50. data/lib/rubyrep/syncers/two_way_syncer.rb +174 -0
  51. data/lib/rubyrep/table_scan.rb +54 -0
  52. data/lib/rubyrep/table_scan_helper.rb +46 -0
  53. data/lib/rubyrep/table_sorter.rb +70 -0
  54. data/lib/rubyrep/table_spec_resolver.rb +142 -0
  55. data/lib/rubyrep/table_sync.rb +90 -0
  56. data/lib/rubyrep/task_sweeper.rb +77 -0
  57. data/lib/rubyrep/trigger_mode_switcher.rb +63 -0
  58. data/lib/rubyrep/type_casting_cursor.rb +31 -0
  59. data/lib/rubyrep/uninstall_runner.rb +93 -0
  60. data/lib/rubyrep/version.rb +9 -0
  61. data/rubyrep +8 -0
  62. data/rubyrep.bat +4 -0
  63. data/setup.rb +1585 -0
  64. data/spec/base_runner_spec.rb +218 -0
  65. data/spec/buffered_committer_spec.rb +274 -0
  66. data/spec/command_runner_spec.rb +145 -0
  67. data/spec/committers_spec.rb +178 -0
  68. data/spec/configuration_spec.rb +203 -0
  69. data/spec/connection_extender_interface_spec.rb +141 -0
  70. data/spec/connection_extenders_registration_spec.rb +164 -0
  71. data/spec/database_proxy_spec.rb +48 -0
  72. data/spec/database_rake_spec.rb +40 -0
  73. data/spec/db_specific_connection_extenders_spec.rb +34 -0
  74. data/spec/db_specific_replication_extenders_spec.rb +38 -0
  75. data/spec/direct_table_scan_spec.rb +61 -0
  76. data/spec/dolphins.jpg +0 -0
  77. data/spec/generate_runner_spec.rb +84 -0
  78. data/spec/initializer_spec.rb +46 -0
  79. data/spec/log_helper_spec.rb +39 -0
  80. data/spec/logged_change_loader_spec.rb +68 -0
  81. data/spec/logged_change_spec.rb +470 -0
  82. data/spec/noisy_connection_spec.rb +78 -0
  83. data/spec/postgresql_replication_spec.rb +48 -0
  84. data/spec/postgresql_schema_support_spec.rb +212 -0
  85. data/spec/postgresql_support_spec.rb +63 -0
  86. data/spec/progress_bar_spec.rb +77 -0
  87. data/spec/proxied_table_scan_spec.rb +151 -0
  88. data/spec/proxy_block_cursor_spec.rb +197 -0
  89. data/spec/proxy_connection_spec.rb +423 -0
  90. data/spec/proxy_cursor_spec.rb +56 -0
  91. data/spec/proxy_row_cursor_spec.rb +66 -0
  92. data/spec/proxy_runner_spec.rb +70 -0
  93. data/spec/replication_difference_spec.rb +161 -0
  94. data/spec/replication_extender_interface_spec.rb +367 -0
  95. data/spec/replication_extenders_spec.rb +32 -0
  96. data/spec/replication_helper_spec.rb +178 -0
  97. data/spec/replication_initializer_spec.rb +509 -0
  98. data/spec/replication_run_spec.rb +443 -0
  99. data/spec/replication_runner_spec.rb +254 -0
  100. data/spec/replicators_spec.rb +36 -0
  101. data/spec/rubyrep_spec.rb +8 -0
  102. data/spec/scan_detail_reporter_spec.rb +119 -0
  103. data/spec/scan_progress_printers_spec.rb +68 -0
  104. data/spec/scan_report_printers_spec.rb +67 -0
  105. data/spec/scan_runner_spec.rb +50 -0
  106. data/spec/scan_summary_reporter_spec.rb +61 -0
  107. data/spec/session_spec.rb +253 -0
  108. data/spec/spec.opts +1 -0
  109. data/spec/spec_helper.rb +305 -0
  110. data/spec/strange_name_support_spec.rb +135 -0
  111. data/spec/sync_helper_spec.rb +169 -0
  112. data/spec/sync_runner_spec.rb +78 -0
  113. data/spec/syncers_spec.rb +171 -0
  114. data/spec/table_scan_helper_spec.rb +36 -0
  115. data/spec/table_scan_spec.rb +49 -0
  116. data/spec/table_sorter_spec.rb +30 -0
  117. data/spec/table_spec_resolver_spec.rb +111 -0
  118. data/spec/table_sync_spec.rb +140 -0
  119. data/spec/task_sweeper_spec.rb +47 -0
  120. data/spec/trigger_mode_switcher_spec.rb +83 -0
  121. data/spec/two_way_replicator_spec.rb +721 -0
  122. data/spec/two_way_syncer_spec.rb +256 -0
  123. data/spec/type_casting_cursor_spec.rb +50 -0
  124. data/spec/uninstall_runner_spec.rb +93 -0
  125. metadata +190 -0
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ describe NoisyConnection do
6
+ before(:each) do
7
+ Initializer.configuration = proxied_config
8
+ @connection = ProxyConnection.new Initializer.configuration.left
9
+ @connection.send(:extend, NoisyConnection)
10
+ @connection.sweeper = TaskSweeper.new(1)
11
+ end
12
+
13
+ it "select_cursor should return correct results" do
14
+ @connection.sweeper.should_receive(:ping).exactly(4).times
15
+ @connection.select_record(:table => 'scanner_records').should == {
16
+ 'id' => 1,
17
+ 'name' => 'Alice - exists in both databases'
18
+ }
19
+ end
20
+
21
+ it "insert_record should write nil values correctly" do
22
+ @connection.sweeper.should_receive(:ping).exactly(2).times
23
+ @connection.begin_db_transaction
24
+ begin
25
+ @connection.insert_record('extender_combined_key', 'first_id' => 8, 'second_id' => '9', 'name' => nil)
26
+ @connection.select_one(
27
+ "select name from extender_combined_key where (first_id, second_id) = (8, 9)"
28
+ ).should == {"name" => nil}
29
+ ensure
30
+ @connection.rollback_db_transaction
31
+ end
32
+ end
33
+
34
+ it "update_record should update the specified record" do
35
+ @connection.sweeper.should_receive(:ping).exactly(2).times
36
+ @connection.begin_db_transaction
37
+ begin
38
+ @connection.update_record('scanner_records', 'id' => 1, 'name' => 'update_test')
39
+ @connection.select_one(
40
+ "select name from scanner_records where id = 1"
41
+ ).should == {'name' => 'update_test'}
42
+ ensure
43
+ @connection.rollback_db_transaction
44
+ end
45
+ end
46
+
47
+ it "delete_record should delete the specified record" do
48
+ @connection.sweeper.should_receive(:ping).exactly(2).times
49
+ @connection.begin_db_transaction
50
+ begin
51
+ @connection.delete_record('extender_combined_key', 'first_id' => 1, 'second_id' => '1', 'name' => 'xy')
52
+ @connection.select_one(
53
+ "select first_id, second_id, name
54
+ from extender_combined_key where (first_id, second_id) = (1, 1)") \
55
+ .should be_nil
56
+ ensure
57
+ @connection.rollback_db_transaction
58
+ end
59
+ end
60
+
61
+ it "commit_db_transaction should update TaskSweeper" do
62
+ @connection.begin_db_transaction
63
+ initializer = ReplicationInitializer.new Session.new(standard_config)
64
+ begin
65
+ @connection.execute "insert into scanner_records(id,name) values(99, 'bla')"
66
+ @connection.sweeper.should_receive(:ping).exactly(2).times
67
+ @connection.commit_db_transaction
68
+ initializer.silence_ddl_notices(:left) do # avoid PostgreSQL warning that no transaction is open
69
+ @connection.rollback_db_transaction
70
+ end
71
+ @connection.select_one("select name from scanner_records where id = 99")['name'].
72
+ should == 'bla'
73
+ ensure
74
+ @connection.execute "delete from scanner_records where id = 99"
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'yaml'
3
+ require 'config/test_config.rb'
4
+
5
+ include RR
6
+
7
+ describe "PostgreSQLReplication", :shared => true do
8
+ before(:each) do
9
+ end
10
+
11
+ it "create_replication_trigger should also work if language plpgsql does not yet exist" do
12
+ session = nil
13
+ begin
14
+ session = Session.new
15
+ session.left.begin_db_transaction
16
+ unless session.left.select_all("select lanname from pg_language where lanname = 'plpgsql'").empty?
17
+ session.left.execute "DROP LANGUAGE plpgsql"
18
+ end
19
+ params = {
20
+ :trigger_name => 'rr_trigger_test',
21
+ :table => 'trigger_test',
22
+ :keys => ['first_id', 'second_id'],
23
+ :log_table => 'rr_pending_changes',
24
+ :key_sep => '|',
25
+ :exclude_rr_activity => false,
26
+ }
27
+ session.left.create_replication_trigger params
28
+ session.left.insert_record 'trigger_test', {
29
+ 'first_id' => 1,
30
+ 'second_id' => 2,
31
+ 'name' => 'bla'
32
+ }
33
+
34
+ row = session.left.select_one("select * from rr_pending_changes")
35
+ row.delete 'id'
36
+ row.delete 'change_time'
37
+ row.should == {
38
+ 'change_table' => 'trigger_test',
39
+ 'change_key' => 'first_id|1|second_id|2',
40
+ 'change_new_key' => nil,
41
+ 'change_type' => 'I'
42
+ }
43
+
44
+ ensure
45
+ session.left.rollback_db_transaction if session
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,212 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ require File.dirname(__FILE__) + "/../config/test_config.rb"
6
+
7
+ describe "PostgreSQL schema support" do
8
+ before(:each) do
9
+ config = deep_copy(standard_config)
10
+ config.options[:rep_prefix] = 'rx'
11
+ config.left[:schema_search_path] = 'rr'
12
+ config.right[:schema_search_path] = 'rr'
13
+ Initializer.configuration = config
14
+ end
15
+
16
+ after(:each) do
17
+ end
18
+
19
+ if Initializer.configuration.left[:adapter] == 'postgresql'
20
+ it "tables should show the tables from the schema and no others" do
21
+ session = Session.new
22
+ session.left.tables.include?('rr_simple').should be_true
23
+ session.left.tables.include?('scanner_records').should be_false
24
+ end
25
+
26
+ it "tables should not show the tables from other schemas" do
27
+ session = Session.new standard_config
28
+ session.left.tables.include?('scanner_records').should be_true
29
+ session.left.tables.include?('rr_simple').should be_false
30
+ end
31
+
32
+ it "primary_key_names should work" do
33
+ session = Session.new
34
+ session.left.primary_key_names('rr_simple').should == ['id']
35
+ end
36
+
37
+ it "primary_key_names should pick the table in the target schema" do
38
+ session = Session.new
39
+ session.left.primary_key_names('rr_duplicate').should == ['id']
40
+ end
41
+
42
+ it "column_names should work" do
43
+ session = Session.new
44
+ session.left.column_names('rr_simple').should == ['id', 'name']
45
+ end
46
+
47
+ it "column_names should pick the table in the target schema" do
48
+ session = Session.new
49
+ session.left.column_names('rr_duplicate').should == ['id', 'name']
50
+ end
51
+
52
+ it "referenced_tables should work" do
53
+ session = Session.new
54
+ session.left.referenced_tables(['rr_referencing']).should == {
55
+ 'rr_referencing' => ['rr_referenced']
56
+ }
57
+ end
58
+
59
+ it "table_select_query should work" do
60
+ session = Session.new
61
+ session.left.table_select_query('rr_simple').
62
+ should == 'select "id", "name" from "rr_simple" order by "id"'
63
+ end
64
+
65
+ it "TypeCastingCursor should work" do
66
+ session = Session.new
67
+ org_cursor = session.left.select_cursor(
68
+ :query => "select id, name from rr_simple where id = 1",
69
+ :type_cast => false
70
+ )
71
+ cursor = TypeCastingCursor.new session.left, 'rr_simple', org_cursor
72
+
73
+ row = cursor.next_row
74
+
75
+ row.should == {
76
+ 'id' => 1,
77
+ 'name' => 'bla'
78
+ }
79
+ end
80
+
81
+ it "sequence_values should pick the table in the target schema" do
82
+ session = Session.new
83
+ session.left.sequence_values('rx', 'rr_duplicate').keys.should == ["rr_duplicate_id_seq"]
84
+ end
85
+
86
+ it "clear_sequence_setup should pick the table in the target schema" do
87
+ session = nil
88
+ begin
89
+ session = Session.new
90
+ initializer = ReplicationInitializer.new(session)
91
+ session.left.begin_db_transaction
92
+ session.right.begin_db_transaction
93
+ table_pair = {:left => 'rr_duplicate', :right => 'rr_duplicate'}
94
+ initializer.ensure_sequence_setup table_pair, 5, 2, 1
95
+ id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
96
+ (id2 - id1).should == 5
97
+ (id1 % 5).should == 2
98
+
99
+ initializer.clear_sequence_setup :left, 'rr_duplicate'
100
+ id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
101
+ (id2 - id1).should == 1
102
+ ensure
103
+ [:left, :right].each do |database|
104
+ initializer.clear_sequence_setup database, 'rr_duplicate' rescue nil if session
105
+ session.send(database).execute "delete from rr_duplicate" rescue nil if session
106
+ session.send(database).rollback_db_transaction rescue nil if session
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ it "sequence setup should work" do
113
+ session = nil
114
+ begin
115
+ session = Session.new
116
+ initializer = ReplicationInitializer.new(session)
117
+ session.left.begin_db_transaction
118
+ session.right.begin_db_transaction
119
+ table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
120
+ initializer.ensure_sequence_setup table_pair, 5, 2, 1
121
+ id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
122
+ (id2 - id1).should == 5
123
+ (id1 % 5).should == 2
124
+ ensure
125
+ [:left, :right].each do |database|
126
+ initializer.clear_sequence_setup database, 'rr_sequence_test' rescue nil if session
127
+ session.send(database).execute "delete from rr_sequence_test" rescue nil if session
128
+ session.send(database).rollback_db_transaction rescue nil if session
129
+ end
130
+ end
131
+ end
132
+
133
+ it "clear_sequence_setup should work" do
134
+ session = nil
135
+ begin
136
+ session = Session.new
137
+ initializer = ReplicationInitializer.new(session)
138
+ session.left.begin_db_transaction
139
+ session.right.begin_db_transaction
140
+ table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
141
+ initializer.ensure_sequence_setup table_pair, 5, 2, 2
142
+ initializer.clear_sequence_setup :left, 'rr_sequence_test'
143
+ id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
144
+ (id2 - id1).should == 1
145
+ ensure
146
+ [:left, :right].each do |database|
147
+ initializer.clear_sequence_setup database, 'rr_sequence_test' if session
148
+ session.send(database).execute "delete from rr_sequence_test" if session
149
+ session.send(database).rollback_db_transaction if session
150
+ end
151
+ end
152
+ end
153
+
154
+ it "initializer should create tables in target schema" do
155
+ session = nil
156
+ begin
157
+ config = deep_copy(Initializer.configuration)
158
+ config.options[:rep_prefix] = 'ry'
159
+ session = Session.new config
160
+ session.left.begin_db_transaction
161
+
162
+ initializer = ReplicationInitializer.new(session)
163
+ initializer.create_change_log(:left)
164
+
165
+ # no exception ==> means table was created in target schema
166
+ session.left.select_one("select id from rr.ry_pending_changes")
167
+ ensure
168
+ session.left.rollback_db_transaction if session
169
+ end
170
+ end
171
+
172
+ it "create_trigger, trigger_exists? and drop_trigger should work" do
173
+ session = nil
174
+ begin
175
+ session = Session.new
176
+ initializer = ReplicationInitializer.new(session)
177
+ session.left.begin_db_transaction
178
+
179
+ initializer.create_trigger :left, 'rr_trigger_test'
180
+ initializer.trigger_exists?(:left, 'rr_trigger_test').
181
+ should be_true
182
+
183
+ # Verify that the trigger can find the pending_changes table even if
184
+ # current search_path does not include it.
185
+ session.left.execute "set search_path = 'public'"
186
+ session.left.execute <<-EOF
187
+ insert into rr.rr_trigger_test(first_id, second_id) values(10, 11)
188
+ EOF
189
+ session.left.execute "set search_path = 'rr'"
190
+ session.left.select_one("select change_key from rx_pending_changes")['change_key'].
191
+ should == "first_id|10|second_id|11"
192
+
193
+ initializer.drop_trigger(:left, 'rr_trigger_test')
194
+ initializer.trigger_exists?(:left, 'rr_trigger_test').
195
+ should be_false
196
+ ensure
197
+ session.left.rollback_db_transaction if session
198
+ end
199
+ end
200
+
201
+ it "should work with complex search paths" do
202
+ config = deep_copy(standard_config)
203
+ config.left[:schema_search_path] = 'public,rr'
204
+ config.right[:schema_search_path] = 'public,rr'
205
+ session = Session.new(config)
206
+
207
+ tables = session.left.tables
208
+ tables.include?('rr_simple').should be_true
209
+ tables.include?('scanner_records').should be_true
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ require File.dirname(__FILE__) + "/../config/test_config.rb"
6
+
7
+ describe "PostgreSQL support" do
8
+ before(:each) do
9
+ Initializer.configuration = standard_config
10
+ end
11
+
12
+ after(:each) do
13
+ end
14
+
15
+ if Initializer.configuration.left[:adapter] == 'postgresql'
16
+
17
+ it "should read & write microsecond times" do
18
+ session = nil
19
+ begin
20
+ session = Session.new
21
+ session.left.begin_db_transaction
22
+ session.left.insert_record('extender_type_check',
23
+ {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 20, 48, 1, 543)}
24
+ )
25
+
26
+ org_cursor = session.left.select_cursor(
27
+ :query => "select id, timestamp from extender_type_check where id = 2",
28
+ :type_cast => false
29
+ )
30
+ cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
31
+
32
+ row = cursor.next_row
33
+ row['timestamp'].usec.should == 543
34
+ cursor.clear
35
+ ensure
36
+ session.left.rollback_db_transaction if session
37
+ end
38
+ end
39
+
40
+ it "should not round microsecond times to incorrect value" do
41
+ session = nil
42
+ begin
43
+ session = Session.new
44
+ session.left.begin_db_transaction
45
+ session.left.insert_record('extender_type_check',
46
+ {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 13, 37, 11, 126291)}
47
+ )
48
+
49
+ org_cursor = session.left.select_cursor(
50
+ :query => "select id, timestamp from extender_type_check where id = 2",
51
+ :type_cast => false
52
+ )
53
+ cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
54
+
55
+ row = cursor.next_row
56
+ row['timestamp'].usec.should == 126291
57
+ cursor.clear
58
+ ensure
59
+ session.left.rollback_db_transaction if session
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+ include ScanProgressPrinters
5
+
6
+ describe ProgressBar do
7
+ before(:each) do
8
+ @org_stdout = $stdout
9
+ $stdout = StringIO.new
10
+ @old_arg = ProgressBar.arg
11
+ end
12
+
13
+ after(:each) do
14
+ ProgressBar.arg = @old_arg
15
+ $stdout = @org_stdout
16
+ end
17
+
18
+ it "arg should store the command line argument and max_markers return the correct marker number" do
19
+ ProgressBar.arg = nil
20
+ ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == ProgressBar::MAX_MARKERS
21
+ ProgressBar.arg = "2"
22
+ ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == 2
23
+ end
24
+
25
+ it "step should use ANSI codes if options :use_ansi is set" do
26
+ session = Session.new(deep_copy(standard_config))
27
+ session.configuration.options[:use_ansi] = true
28
+ bar = ProgressBar.new(10, session, 'bla', 'blub')
29
+ bar.step 1
30
+ bar.step 1
31
+ $stdout.string.should =~ Regexp.new(Regexp.escape("\e[1"))
32
+ end
33
+
34
+ it "step should not use ANSI codes if options :use_ansi is not true" do
35
+ session = Session.new(deep_copy(standard_config))
36
+ session.configuration.options[:use_ansi] = false
37
+ bar = ProgressBar.new(10, session, 'bla', 'blub')
38
+ bar.step 1
39
+ bar.step 1
40
+ $stdout.string.should_not =~ Regexp.new(Regexp.escape("\e[1"))
41
+ end
42
+
43
+ it "should register itself with ScanRunner" do
44
+ RR::ScanProgressPrinters.printers[:progress_bar][:printer_class].
45
+ should == ProgressBar
46
+ end
47
+
48
+ it "step should print the correct progress" do
49
+ bar = ProgressBar.new(1000, Session.new(standard_config), 'bla', 'blub')
50
+ bar.step 200
51
+ bar.step 300
52
+ $stdout.string.count('.').should == ProgressBar::MAX_MARKERS / 2
53
+ bar.step 500
54
+ $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
55
+ end
56
+
57
+ it "step should work around weird floating point rounding issues" do
58
+ bar = ProgressBar.new(56, Session.new(standard_config), 'bla', 'blub')
59
+ (1..56).each {bar.step 1}
60
+ $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
61
+ end
62
+
63
+ it "if max_steps is 0, any step call should go to 100% progress" do
64
+ config = deep_copy(standard_config)
65
+ config.options[:use_ansi] = true
66
+ bar = ProgressBar.new(0, Session.new(config), 'bla', 'blub')
67
+ bar.step
68
+ $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
69
+ $stdout.string.should =~ /100%/
70
+
71
+ # Ensure we don't go over 100%
72
+ $stdout = StringIO.new
73
+ bar.step
74
+ $stdout.string.should == ''
75
+ end
76
+
77
+ end