slacker 1.0.14 → 1.0.15

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