slacker 1.0.14 → 1.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/README.markdown +22 -22
  4. data/Rakefile +11 -11
  5. data/bin/slacker +32 -32
  6. data/bin/slacker_new +34 -34
  7. data/lib/slacker.rb +180 -175
  8. data/lib/slacker/application.rb +224 -214
  9. data/lib/slacker/command_line_formatter.rb +61 -61
  10. data/lib/slacker/configuration.rb +59 -59
  11. data/lib/slacker/formatter.rb +14 -14
  12. data/lib/slacker/query_result_matcher.rb +178 -178
  13. data/lib/slacker/rspec_ext.rb +57 -57
  14. data/lib/slacker/rspec_monkey.rb +7 -7
  15. data/lib/slacker/sql.rb +39 -39
  16. data/lib/slacker/sql_preprocessor.rb +23 -23
  17. data/lib/slacker/string_helper.rb +16 -16
  18. data/lib/slacker/version.rb +3 -3
  19. data/lib/slacker_new/project/data/sample_1/my_table_expected_power_results.csv +11 -11
  20. data/lib/slacker_new/project/data/sample_1/my_table_initial_data.csv +11 -11
  21. data/lib/slacker_new/project/data/sample_1/numbers_expected_output.csv +3 -3
  22. data/lib/slacker_new/project/database.yml +9 -9
  23. data/lib/slacker_new/project/lib/helpers/my_helper.rb +1 -1
  24. data/lib/slacker_new/project/spec/sample_1.rb +66 -66
  25. data/lib/slacker_new/project/sql/sample_1/my_table_on_power.sql.erb +1 -1
  26. data/lib/slacker_new/project/sql/sample_1/play_with_numbers.sql.erb +16 -16
  27. data/lib/slacker_new/project/sql/sample_1/sysobjects_with_params.sql.erb +1 -1
  28. data/slacker.gemspec +27 -27
  29. data/spec/application_spec.rb +13 -13
  30. data/spec/query_result_matcher_spec.rb +268 -268
  31. data/spec/rspec_ext_spec.rb +87 -87
  32. data/spec/slacker_spec.rb +59 -59
  33. data/spec/spec_helper.rb +19 -9
  34. data/spec/test_files/matcher/test_1.csv +3 -3
  35. data/spec/test_files/test_slacker_project/data/test_1.csv +3 -3
  36. data/spec/test_files/test_slacker_project/sql/nest/nested_1.sql.erb +1 -1
  37. data/spec/test_files/test_slacker_project/sql/no_params.sql.erb +2 -2
  38. data/spec/test_files/test_slacker_project/sql/params.sql.erb +1 -1
  39. metadata +24 -24
@@ -1,215 +1,225 @@
1
- require 'logger'
2
- require 'rspec/core'
3
- require 'slacker/rspec_monkey'
4
- require 'slacker/rspec_ext'
5
- require 'slacker/string_helper'
6
- require 'odbc'
7
-
8
- module Slacker
9
- class Application
10
- attr_reader :target_folder_structure
11
-
12
- SQL_OPTIONS = <<EOF
13
- set textsize 2147483647;
14
- set language us_english;
15
- set dateformat mdy;
16
- set datefirst 7;
17
- set lock_timeout -1;
18
- set quoted_identifier on;
19
- set arithabort on;
20
- set ansi_null_dflt_on on;
21
- set ansi_warnings on;
22
- set ansi_padding on;
23
- set ansi_nulls on;
24
- set concat_null_yields_null on;
25
- EOF
26
-
27
- def initialize(configuration)
28
- @configuration = configuration
29
- @target_folder_structure = ['data', 'debug', 'debug/passed_examples', 'debug/failed_examples', 'sql', 'spec', 'lib', 'lib/helpers']
30
- @error_message = ''
31
- @database = ODBC::Database.new
32
- end
33
-
34
- def print_connection_message
35
- puts "#{@configuration.db_name} (#{@configuration.db_server})" if @configuration.console_enabled
36
- end
37
-
38
- # Customize RSpec and run it
39
- def run
40
- begin
41
- error = catch :error_exit do
42
- print_connection_message
43
- test_folder_structure
44
- cleanup_folders
45
- configure
46
- run_rspec
47
- false # Return false to be stored in error (effectively indicating no error).
48
- end
49
- ensure
50
- cleanup_after_run
51
- end
52
-
53
- if @configuration.console_enabled
54
- puts @error_message if error
55
- else
56
- raise @error_message if error
57
- end
58
-
59
- # Return true if no error occurred, otherwise false.
60
- !error
61
- end
62
-
63
- def run_rspec
64
- RSpec::Core::Runner.disable_autorun!
65
-
66
- RSpec::Core::Runner.run(@configuration.rspec_args,
67
- @configuration.error_stream,
68
- @configuration.output_stream)
69
- end
70
-
71
- # Configure Slacker
72
- def configure
73
- configure_db
74
- configure_rspec
75
- configure_misc
76
- end
77
-
78
- def cleanup_after_run
79
- @database.disconnect if (@database && @database.connected?)
80
- end
81
-
82
- def cleanup_folders
83
- cleanup_folder('debug/passed_examples')
84
- cleanup_folder('debug/failed_examples')
85
- end
86
-
87
- def cleanup_folder(folder)
88
- folder_path = get_path(folder)
89
- Dir.new(folder_path).each{|file_name| File.delete("#{folder_path}/#{file_name}") if File.file?("#{folder_path}/#{file_name}")}
90
- end
91
-
92
- # Get a path relative to the current path
93
- def get_path(path)
94
- @configuration.expand_path(path)
95
- end
96
-
97
- def configure_misc
98
- # Add the lib folder to the load path
99
- $:.push get_path('lib')
100
- # Mixin the helper modules
101
- mixin_helpers
102
- end
103
-
104
- # Mix in the helper modules
105
- def mixin_helpers
106
- helpers_dir = get_path('lib/helpers')
107
- $:.push helpers_dir
108
- Dir.new(helpers_dir).each do |file_name|
109
- if file_name =~ /\.rb$/
110
- require file_name
111
- module_class = Slacker::StringHelper.constantize(Slacker::StringHelper.camelize(file_name.gsub(/\.rb$/,'')))
112
- RSpec.configure do |config|
113
- config.include(module_class)
114
- end
115
- Slacker.mixin_module(module_class)
116
- end
117
- end
118
- end
119
-
120
- # Configure database connection
121
- def configure_db
122
- drv = ODBC::Driver.new
123
- drv.name = 'Driver1'
124
- drv.attrs.tap do |a|
125
- a['Driver'] = '{SQL Server}'
126
- a['Server']= @configuration.db_server
127
- a['Database']= @configuration.db_name
128
- a['Uid'] = @configuration.db_user
129
- a['Pwd'] = @configuration.db_password
130
- a['TDS_Version'] = '7.0' #Used by the linux driver
131
- end
132
-
133
- begin
134
- @database.drvconnect(drv)
135
- rescue ODBC::Error => e
136
- throw_error("#{e.class}: #{e.message}")
137
- end
138
- end
139
-
140
- # Run a script against the currently configured database
141
- def query_script(sql)
142
- results = []
143
- begin
144
- st = @database.run(sql)
145
- begin
146
- if st.ncols > 0
147
- rows = []
148
- st.each_hash(false, true){|row| rows << row}
149
- results << rows
150
- end
151
- end while(st.more_results)
152
- ensure
153
- st.drop unless st.nil?
154
- end
155
- results.count > 1 ? results : results.first
156
- end
157
-
158
- # Customize RSpec
159
- def configure_rspec
160
- before_proc = lambda do |example|
161
- # Initialize the example's SQL
162
- example.metadata[:sql] = ''
163
- Slacker.query_script(example, 'begin transaction;', 'Initiate the example script')
164
- Slacker.query_script(example, SQL_OPTIONS, 'Set default options')
165
- end
166
-
167
- after_proc = lambda do |example|
168
- Slacker.query_script(example, 'if @@trancount > 0 rollback transaction;', 'Rollback the changes made by the example script')
169
- end
170
-
171
- # Reset RSpec through a monkey-patched method
172
- RSpec.slacker_reset
173
-
174
- RSpec.configure do |config|
175
-
176
- # Expose the current example to the ExampleGroup extension
177
- # This is necessary in order to have this work with RSpec 3
178
- config.expose_current_running_example_as :example
179
-
180
- # Global "before" hooks to begin a transaction
181
- config.before(:each) do
182
- before_proc.call(example)
183
- end
184
-
185
- # Global "after" hooks to rollback a transaction
186
- config.after(:each) do
187
- after_proc.call(example)
188
- end
189
-
190
- # Slacker's RSpec extension module
191
- config.include(Slacker::RSpecExt)
192
- config.extend(Slacker::RSpecExt)
193
-
194
- config.output_stream = @configuration.output_stream
195
- config.error_stream = @configuration.error_stream
196
-
197
- config.add_formatter(Slacker::CommandLineFormatter)
198
- end
199
- end
200
-
201
- # Tests the current folder's structure
202
- def test_folder_structure()
203
- target_folder_structure.each do |dir|
204
- if !File.directory?(get_path(dir))
205
- throw_error("Cannot find directory \"#{get_path(dir)}\"")
206
- end
207
- end
208
- end
209
-
210
- def throw_error(msg)
211
- @error_message = msg
212
- throw :error_exit, true
213
- end
214
- end
1
+ require 'logger'
2
+ require 'rspec/core'
3
+ require 'fileutils'
4
+ require 'slacker/rspec_monkey'
5
+ require 'slacker/rspec_ext'
6
+ require 'slacker/string_helper'
7
+ require 'odbc'
8
+
9
+ module Slacker
10
+ class Application
11
+ attr_reader :target_folder_structure, :temp_folders
12
+
13
+ SQL_OPTIONS = <<EOF
14
+ set textsize 2147483647;
15
+ set language us_english;
16
+ set dateformat mdy;
17
+ set datefirst 7;
18
+ set lock_timeout -1;
19
+ set quoted_identifier on;
20
+ set arithabort on;
21
+ set ansi_null_dflt_on on;
22
+ set ansi_warnings on;
23
+ set ansi_padding on;
24
+ set ansi_nulls on;
25
+ set concat_null_yields_null on;
26
+ EOF
27
+
28
+ def initialize(configuration)
29
+ @configuration = configuration
30
+ @temp_folders = ['debug/passed_examples', 'debug/failed_examples']
31
+ @target_folder_structure = ['data', 'debug/passed_examples', 'debug/failed_examples', 'sql', 'spec', 'lib', 'lib/helpers']
32
+ @error_message = ''
33
+ @database = ODBC::Database.new
34
+ end
35
+
36
+ def print_connection_message
37
+ puts "#{@configuration.db_name} (#{@configuration.db_server})" if @configuration.console_enabled
38
+ end
39
+
40
+ # Customize RSpec and run it
41
+ def run
42
+ begin
43
+ error = catch :error_exit do
44
+ print_connection_message
45
+ create_temp_folders
46
+ test_folder_structure
47
+ cleanup_folders
48
+ configure
49
+ run_rspec
50
+ false # Return false to be stored in error (effectively indicating no error).
51
+ end
52
+ ensure
53
+ cleanup_after_run
54
+ end
55
+
56
+ if @configuration.console_enabled
57
+ puts @error_message if error
58
+ else
59
+ raise @error_message if error
60
+ end
61
+
62
+ # Return true if no error occurred, otherwise false.
63
+ !error
64
+ end
65
+
66
+ def run_rspec
67
+ RSpec::Core::Runner.disable_autorun!
68
+
69
+ RSpec::Core::Runner.run(@configuration.rspec_args,
70
+ @configuration.error_stream,
71
+ @configuration.output_stream)
72
+ end
73
+
74
+ # Configure Slacker
75
+ def configure
76
+ configure_db
77
+ configure_rspec
78
+ configure_misc
79
+ end
80
+
81
+ def cleanup_after_run
82
+ @database.disconnect if (@database && @database.connected?)
83
+ end
84
+
85
+ def cleanup_folders
86
+ cleanup_folder('debug/passed_examples')
87
+ cleanup_folder('debug/failed_examples')
88
+ end
89
+
90
+ def cleanup_folder(folder)
91
+ folder_path = get_path(folder)
92
+ Dir.new(folder_path).each{|file_name| File.delete("#{folder_path}/#{file_name}") if File.file?("#{folder_path}/#{file_name}")}
93
+ end
94
+
95
+ # Get a path relative to the current path
96
+ def get_path(path)
97
+ @configuration.expand_path(path)
98
+ end
99
+
100
+ def configure_misc
101
+ # Add the lib folder to the load path
102
+ $:.push get_path('lib')
103
+ # Mixin the helper modules
104
+ mixin_helpers
105
+ end
106
+
107
+ # Mix in the helper modules
108
+ def mixin_helpers
109
+ helpers_dir = get_path('lib/helpers')
110
+ $:.push helpers_dir
111
+ Dir.new(helpers_dir).each do |file_name|
112
+ if file_name =~ /\.rb$/
113
+ require file_name
114
+ module_class = Slacker::StringHelper.constantize(Slacker::StringHelper.camelize(file_name.gsub(/\.rb$/,'')))
115
+ RSpec.configure do |config|
116
+ config.include(module_class)
117
+ end
118
+ Slacker.mixin_module(module_class)
119
+ end
120
+ end
121
+ end
122
+
123
+ # Configure database connection
124
+ def configure_db
125
+ drv = ODBC::Driver.new
126
+ drv.name = 'Driver1'
127
+ drv.attrs.tap do |a|
128
+ a['Driver'] = '{SQL Server}'
129
+ a['Server']= @configuration.db_server
130
+ a['Database']= @configuration.db_name
131
+ a['Uid'] = @configuration.db_user
132
+ a['Pwd'] = @configuration.db_password
133
+ a['TDS_Version'] = '7.0' #Used by the linux driver
134
+ end
135
+
136
+ begin
137
+ @database.drvconnect(drv)
138
+ rescue ODBC::Error => e
139
+ throw_error("#{e.class}: #{e.message}")
140
+ end
141
+ end
142
+
143
+ # Run a script against the currently configured database
144
+ def query_script(sql)
145
+ results = []
146
+ begin
147
+ st = @database.run(sql)
148
+ begin
149
+ if st.ncols > 0
150
+ rows = []
151
+ st.each_hash(false, true){|row| rows << row}
152
+ results << rows
153
+ end
154
+ end while(st.more_results)
155
+ ensure
156
+ st.drop unless st.nil?
157
+ end
158
+ results.count > 1 ? results : results.first
159
+ end
160
+
161
+ # Customize RSpec
162
+ def configure_rspec
163
+ before_proc = lambda do |example|
164
+ # Initialize the example's SQL
165
+ example.metadata[:sql] = ''
166
+ Slacker.query_script(example, 'begin transaction;', 'Initiate the example script')
167
+ Slacker.query_script(example, SQL_OPTIONS, 'Set default options')
168
+ end
169
+
170
+ after_proc = lambda do |example|
171
+ Slacker.query_script(example, 'if @@trancount > 0 rollback transaction;', 'Rollback the changes made by the example script')
172
+ end
173
+
174
+ # Reset RSpec through a monkey-patched method
175
+ RSpec.slacker_reset
176
+
177
+ RSpec.configure do |config|
178
+
179
+ # Expose the current example to the ExampleGroup extension
180
+ # This is necessary in order to have this work with RSpec 3
181
+ config.expose_current_running_example_as :example
182
+
183
+ # Global "before" hooks to begin a transaction
184
+ config.before(:each) do
185
+ before_proc.call(example)
186
+ end
187
+
188
+ # Global "after" hooks to rollback a transaction
189
+ config.after(:each) do
190
+ after_proc.call(example)
191
+ end
192
+
193
+ # Slacker's RSpec extension module
194
+ config.include(Slacker::RSpecExt)
195
+ config.extend(Slacker::RSpecExt)
196
+
197
+ config.output_stream = @configuration.output_stream
198
+ config.error_stream = @configuration.error_stream
199
+
200
+ config.add_formatter(Slacker::CommandLineFormatter)
201
+ end
202
+ end
203
+
204
+ # Tests the current folder's structure
205
+ def test_folder_structure()
206
+ target_folder_structure.each do |dir|
207
+ if !File.directory?(get_path(dir))
208
+ throw_error("Cannot find directory \"#{get_path(dir)}\"")
209
+ end
210
+ end
211
+ end
212
+
213
+ # Create temporary folders if they don't exist
214
+ def create_temp_folders()
215
+ temp_folders.each do |dir|
216
+ FileUtils.mkdir_p(dir)
217
+ end
218
+ end
219
+
220
+ def throw_error(msg)
221
+ @error_message = msg
222
+ throw :error_exit, true
223
+ end
224
+ end
215
225
  end
@@ -1,61 +1,61 @@
1
- require 'slacker/formatter'
2
- require 'rspec/core/formatters/progress_formatter'
3
-
4
- module Slacker
5
- class CommandLineFormatter < RSpec::Core::Formatters::ProgressFormatter
6
- include Slacker::Formatter
7
- RSpec::Core::Formatters.register self, :example_passed, :example_failed
8
-
9
- def initialize(output)
10
- super(output)
11
- @failed_examples_count = 0
12
- @passed_examples_count = 0
13
- end
14
-
15
- def example_passed(notification)
16
- super(notification)
17
- process_example_debug_output(notification, false)
18
- end
19
-
20
- def example_failed(notification)
21
- super(notification)
22
- process_example_debug_output(notification, true)
23
- end
24
-
25
- private
26
-
27
- def process_example_debug_output(notification, example_failed)
28
- if example_failed
29
- @failed_examples_count += 1
30
- debug_output(notification, Slacker.configuration.expand_path('debug/failed_examples'), @failed_examples_count, example_failed)
31
- else
32
- @passed_examples_count += 1
33
- debug_output(notification, Slacker.configuration.expand_path('debug/passed_examples'), @passed_examples_count, example_failed)
34
- end
35
- end
36
-
37
- def debug_output(notification, out_folder, file_number, example_failed)
38
- # Write out the SQL
39
- File.open("#{out_folder}/example_#{'%03d' % file_number}.sql", 'w') do |out_file|
40
- out_file.write(get_formatted_example_sql(notification, example_failed))
41
- end
42
- end
43
-
44
- def get_formatted_example_sql(notification, example_failed)
45
- example = notification.example
46
- sql = <<EOF
47
- -- Example "#{example.metadata[:full_description]}"
48
- -- #{example.metadata[:location]}
49
- -- Executed at #{example.execution_result.started_at}
50
-
51
- #{example.metadata[:sql]}
52
-
53
- -- SLACKER RESULTS
54
- -- *******************************************
55
- #{example_failed ? example_failure_text(notification).split("\n").collect{|line| '-- ' + line}.join("\n") : '-- Example Passed OK'}
56
- -- *******************************************
57
- EOF
58
- sql.strip
59
- end
60
- end
61
- end
1
+ require 'slacker/formatter'
2
+ require 'rspec/core/formatters/progress_formatter'
3
+
4
+ module Slacker
5
+ class CommandLineFormatter < RSpec::Core::Formatters::ProgressFormatter
6
+ include Slacker::Formatter
7
+ RSpec::Core::Formatters.register self, :example_passed, :example_failed
8
+
9
+ def initialize(output)
10
+ super(output)
11
+ @failed_examples_count = 0
12
+ @passed_examples_count = 0
13
+ end
14
+
15
+ def example_passed(notification)
16
+ super(notification)
17
+ process_example_debug_output(notification, false)
18
+ end
19
+
20
+ def example_failed(notification)
21
+ super(notification)
22
+ process_example_debug_output(notification, true)
23
+ end
24
+
25
+ private
26
+
27
+ def process_example_debug_output(notification, example_failed)
28
+ if example_failed
29
+ @failed_examples_count += 1
30
+ debug_output(notification, Slacker.configuration.expand_path('debug/failed_examples'), @failed_examples_count, example_failed)
31
+ else
32
+ @passed_examples_count += 1
33
+ debug_output(notification, Slacker.configuration.expand_path('debug/passed_examples'), @passed_examples_count, example_failed)
34
+ end
35
+ end
36
+
37
+ def debug_output(notification, out_folder, file_number, example_failed)
38
+ # Write out the SQL
39
+ File.open("#{out_folder}/example_#{'%03d' % file_number}.sql", 'w') do |out_file|
40
+ out_file.write(get_formatted_example_sql(notification, example_failed))
41
+ end
42
+ end
43
+
44
+ def get_formatted_example_sql(notification, example_failed)
45
+ example = notification.example
46
+ sql = <<EOF
47
+ -- Example "#{example.metadata[:full_description]}"
48
+ -- #{example.metadata[:location]}
49
+ -- Executed at #{example.execution_result.started_at}
50
+
51
+ #{example.metadata[:sql]}
52
+
53
+ -- SLACKER RESULTS
54
+ -- *******************************************
55
+ #{example_failed ? example_failure_text(notification).split("\n").collect{|line| '-- ' + line}.join("\n") : '-- Example Passed OK'}
56
+ -- *******************************************
57
+ EOF
58
+ sql.strip
59
+ end
60
+ end
61
+ end