andyjeffries-rubyrep 1.2.1

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 (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