active_olap 0.0.2

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.
@@ -0,0 +1,312 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/tasklib'
4
+ require 'date'
5
+ require 'git'
6
+
7
+ module GithubGem
8
+
9
+ # Detects the gemspc file of this project using heuristics.
10
+ def self.detect_gemspec_file
11
+ FileList['*.gemspec'].first
12
+ end
13
+
14
+ # Detects the main include file of this project using heuristics
15
+ def self.detect_main_include
16
+ if detect_gemspec_file =~ /^(\.*)\.gemspec$/ && File.exist?("lib/#{$1}.rb")
17
+ "lib/#{$1}.rb"
18
+ elsif FileList['lib/*.rb'].length == 1
19
+ FileList['lib/*.rb'].first
20
+ else
21
+ raise "Could not detect main include file!"
22
+ end
23
+ end
24
+
25
+ class RakeTasks
26
+
27
+ attr_reader :gemspec, :modified_files, :git
28
+ attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
29
+
30
+ # Initializes the settings, yields itself for configuration
31
+ # and defines the rake tasks based on the gemspec file.
32
+ def initialize(task_namespace = :gem)
33
+ @gemspec_file = GithubGem.detect_gemspec_file
34
+ @task_namespace = task_namespace
35
+ @main_include = GithubGem.detect_main_include
36
+ @modified_files = []
37
+ @root_dir = Dir.pwd
38
+ @test_pattern = 'test/**/*_test.rb'
39
+ @spec_pattern = 'spec/**/*_spec.rb'
40
+ @local_branch = 'master'
41
+ @remote = 'origin'
42
+ @remote_branch = 'master'
43
+
44
+ yield(self) if block_given?
45
+
46
+ @git = Git.open(@root_dir)
47
+ load_gemspec!
48
+ define_tasks!
49
+ end
50
+
51
+ protected
52
+
53
+ # Define Unit test tasks
54
+ def define_test_tasks!
55
+ require 'rake/testtask'
56
+
57
+ namespace(:test) do
58
+ Rake::TestTask.new(:basic) do |t|
59
+ t.pattern = test_pattern
60
+ t.verbose = true
61
+ t.libs << 'test'
62
+ end
63
+ end
64
+
65
+ desc "Run all unit tests for #{gemspec.name}"
66
+ task(:test => ['test:basic'])
67
+ end
68
+
69
+ # Defines RSpec tasks
70
+ def define_rspec_tasks!
71
+ require 'spec/rake/spectask'
72
+
73
+ namespace(:spec) do
74
+ desc "Verify all RSpec examples for #{gemspec.name}"
75
+ Spec::Rake::SpecTask.new(:basic) do |t|
76
+ t.spec_files = FileList[spec_pattern]
77
+ end
78
+
79
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
80
+ Spec::Rake::SpecTask.new(:specdoc) do |t|
81
+ t.spec_files = FileList[spec_pattern]
82
+ t.spec_opts << '--format' << 'specdoc' << '--color'
83
+ end
84
+
85
+ desc "Run RCov on specs for #{gemspec.name}"
86
+ Spec::Rake::SpecTask.new(:rcov) do |t|
87
+ t.spec_files = FileList[spec_pattern]
88
+ t.rcov = true
89
+ t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
90
+ end
91
+ end
92
+
93
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
94
+ task(:spec => ['spec:specdoc'])
95
+ end
96
+
97
+ # Defines the rake tasks
98
+ def define_tasks!
99
+
100
+ define_test_tasks! if has_tests?
101
+ define_rspec_tasks! if has_specs?
102
+
103
+ namespace(@task_namespace) do
104
+ desc "Updates the filelist in the gemspec file"
105
+ task(:manifest) { manifest_task }
106
+
107
+ desc "Builds the .gem package"
108
+ task(:build => :manifest) { build_task }
109
+
110
+ desc "Sets the version of the gem in the gemspec"
111
+ task(:set_version => [:check_version, :check_current_branch]) { version_task }
112
+ task(:check_version => :fetch_origin) { check_version_task }
113
+
114
+ task(:fetch_origin) { fetch_origin_task }
115
+ task(:check_current_branch) { check_current_branch_task }
116
+ task(:check_clean_status) { check_clean_status_task }
117
+ task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
118
+
119
+ checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
120
+ checks.unshift('spec:basic') if has_specs?
121
+ checks.unshift('test:basic') if has_tests?
122
+ checks.push << [:check_rubyforge] if gemspec.rubyforge_project
123
+
124
+ desc "Perform all checks that would occur before a release"
125
+ task(:release_checks => checks)
126
+
127
+ release_tasks = [:release_checks, :set_version, :build, :github_release]
128
+ release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
129
+
130
+ desc "Release a new verison of the gem"
131
+ task(:release => release_tasks) { release_task }
132
+
133
+ task(:check_rubyforge) { check_rubyforge_task }
134
+ task(:rubyforge_release) { rubyforge_release_task }
135
+ task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
136
+ task(:tag_version) { tag_version_task }
137
+ task(:commit_modified_files) { commit_modified_files_task }
138
+
139
+ desc "Updates the gem release tasks with the latest version on Github"
140
+ task(:update_tasks) { update_tasks_task }
141
+ end
142
+ end
143
+
144
+ # Updates the files list and test_files list in the gemspec file using the list of files
145
+ # in the repository and the spec/test file pattern.
146
+ def manifest_task
147
+ # Load all the gem's files using "git ls-files"
148
+ repository_files = git.ls_files.keys
149
+ test_files = Dir[test_pattern] + Dir[spec_pattern]
150
+
151
+ update_gemspec(:files, repository_files)
152
+ update_gemspec(:test_files, repository_files & test_files)
153
+ end
154
+
155
+ # Builds the gem
156
+ def build_task
157
+ sh "gem build -q #{gemspec_file}"
158
+ Dir.mkdir('pkg') unless File.exist?('pkg')
159
+ sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
160
+ end
161
+
162
+ # Updates the version number in the gemspec file, the VERSION constant in the main
163
+ # include file and the contents of the VERSION file.
164
+ def version_task
165
+ update_gemspec(:version, ENV['VERSION']) if ENV['VERSION']
166
+ update_gemspec(:date, Date.today)
167
+
168
+ update_version_file(gemspec.version)
169
+ update_version_constant(gemspec.version)
170
+ end
171
+
172
+ def check_version_task
173
+ raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
174
+ proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
175
+ # Loads the latest version number using the created tags
176
+ newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
177
+ raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
178
+ end
179
+
180
+ # Checks whether the current branch is not diverged from the remote branch
181
+ def check_not_diverged_task
182
+ raise "The current branch is diverged from the remote branch!" if git.log.between('HEAD', git.branches["#{remote}/#{remote_branch}"].gcommit).any?
183
+ end
184
+
185
+ # Checks whether the repository status ic clean
186
+ def check_clean_status_task
187
+ raise "The current working copy contains modifications" if git.status.changed.any?
188
+ end
189
+
190
+ # Checks whether the current branch is correct
191
+ def check_current_branch_task
192
+ raise "Currently not on #{local_branch} branch!" unless git.branch.name == local_branch.to_s
193
+ end
194
+
195
+ # Fetches the latest updates from Github
196
+ def fetch_origin_task
197
+ git.fetch('origin')
198
+ end
199
+
200
+ # Commits every file that has been changed by the release task.
201
+ def commit_modified_files_task
202
+ if modified_files.any?
203
+ modified_files.each { |file| git.add(file) }
204
+ git.commit("Released #{gemspec.name} gem version #{gemspec.version}")
205
+ end
206
+ end
207
+
208
+ # Adds a tag for the released version
209
+ def tag_version_task
210
+ git.add_tag("#{gemspec.name}-#{gemspec.version}")
211
+ end
212
+
213
+ # Pushes the changes and tag to github
214
+ def github_release_task
215
+ git.push(remote, remote_branch, true)
216
+ end
217
+
218
+ # Checks whether Rubyforge is configured properly
219
+ def check_rubyforge_task
220
+ raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
221
+ output = `rubyforge names`.split("\n")
222
+ raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
223
+ raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
224
+ end
225
+
226
+ # Task to release the .gem file toRubyforge.
227
+ def rubyforge_release_task
228
+ sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
229
+ end
230
+
231
+ # Gem release task.
232
+ # All work is done by the task's dependencies, so just display a release completed message.
233
+ def release_task
234
+ puts
235
+ puts '------------------------------------------------------------'
236
+ puts "Released #{gemspec.name} version #{gemspec.version}"
237
+ end
238
+
239
+ private
240
+
241
+ # Checks whether this project has any RSpec files
242
+ def has_specs?
243
+ FileList[spec_pattern].any?
244
+ end
245
+
246
+ # Checks whether this project has any unit test files
247
+ def has_tests?
248
+ FileList[test_pattern].any?
249
+ end
250
+
251
+ # Loads the gemspec file
252
+ def load_gemspec!
253
+ @gemspec = eval(File.read(@gemspec_file))
254
+ end
255
+
256
+ # Updates the VERSION file with the new version
257
+ def update_version_file(version)
258
+ if File.exists?('VERSION')
259
+ File.open('VERSION', 'w') { |f| f << version.to_s }
260
+ modified_files << 'VERSION'
261
+ end
262
+ end
263
+
264
+ # Updates the VERSION constant in the main include file if it exists
265
+ def update_version_constant(version)
266
+ file_contents = File.read(main_include)
267
+ if file_contents.sub!(/^(\s+VERSION\s*=\s*)[^\s].*$/) { $1 + version.to_s.inspect }
268
+ File.open(main_include, 'w') { |f| f << file_contents }
269
+ modified_files << main_include
270
+ end
271
+ end
272
+
273
+ # Updates an attribute of the gemspec file.
274
+ # This function will open the file, and search/replace the attribute using a regular expression.
275
+ def update_gemspec(attribute, new_value, literal = false)
276
+
277
+ unless literal
278
+ new_value = case new_value
279
+ when Array then "%w(#{new_value.join(' ')})"
280
+ when Hash, String then new_value.inspect
281
+ when Date then new_value.strftime('%Y-%m-%d').inspect
282
+ else raise "Cannot write value #{new_value.inspect} to gemspec file!"
283
+ end
284
+ end
285
+
286
+ spec = File.read(gemspec_file)
287
+ regexp = Regexp.new('^(\s+\w+\.' + Regexp.quote(attribute.to_s) + '\s*=\s*)[^\s].*$')
288
+ if spec.sub!(regexp) { $1 + new_value }
289
+ File.open(gemspec_file, 'w') { |f| f << spec }
290
+ modified_files << gemspec_file
291
+
292
+ # Reload the gemspec so the changes are incorporated
293
+ load_gemspec!
294
+ end
295
+ end
296
+
297
+ # Updates the tasks file using the latest file found on Github
298
+ def update_tasks_task
299
+ require 'net/http'
300
+
301
+ server = 'github.com'
302
+ path = '/wvanbergen/github-gem/raw/master/tasks/github-gem.rake'
303
+
304
+ Net::HTTP.start(server) do |http|
305
+ response = http.get(path)
306
+ open(__FILE__, "w") { |file| file.write(response.body) }
307
+ end
308
+ puts "Updated gem release tasks file with latest version."
309
+ end
310
+
311
+ end
312
+ end
@@ -0,0 +1,335 @@
1
+ require "#{File.dirname(__FILE__)}/helper"
2
+
3
+ class ActiveOLAP::QueryTest < Test::Unit::TestCase
4
+
5
+ include ActiveOlapTestHelper
6
+
7
+ def setup
8
+ create_db
9
+ create_corpus
10
+ end
11
+
12
+ def teardown
13
+ cleanup_db
14
+ end
15
+
16
+ # --- TESTS ---------------------------------
17
+
18
+ def test_wrong_overlap_dimension_usage
19
+
20
+ begin
21
+ cube = OlapTest.olap_query :with_overlap, :category
22
+ assert false, "An exception should have been thrown"
23
+ rescue
24
+ assert true
25
+ end
26
+
27
+ begin
28
+ cube = OlapTest.olap_query :with_overlap, :aggregate => :avg_int_field
29
+ assert false, "An exception should have been thrown"
30
+ rescue
31
+ assert true
32
+ end
33
+ end
34
+
35
+ def test_with_associations
36
+ cube = OlapTest.olap_query :category, :aggregate => [:count_distinct, :total_price]
37
+ assert_active_olap_cube cube, [5]
38
+ assert_equal 1, cube[:no_category][:count_distinct]
39
+ assert_equal 5.7, cube[:no_category][:total_price]
40
+ assert_equal nil, cube[:first_cat][:total_price]
41
+
42
+ cube = OlapTest.olap_query(:in_association)
43
+ assert_active_olap_cube cube, [3]
44
+ assert_equal 1, cube[:first]
45
+ assert_equal 1, cube[:second]
46
+ assert_equal 4, cube[:other]
47
+ end
48
+
49
+ def test_time_dimension
50
+ cube = OlapTest.olap_query(:the_time)
51
+ assert_active_olap_cube cube, [20]
52
+
53
+ cube = OlapTest.olap_query([:the_time, {:period_count => 10}])
54
+ assert_active_olap_cube cube, [10]
55
+ end
56
+
57
+ def test_with_aggregates
58
+ # defined using a smart symbol
59
+ cube = OlapTest.olap_query(:category, :aggregate => :sum_int_field)
60
+ assert_equal 33, cube[:first_cat]
61
+ assert_equal 77, cube[:second_cat]
62
+ assert_equal 33, cube[:no_category]
63
+ assert_equal nil, cube[:third_cat]
64
+ assert_equal nil, cube[:other]
65
+
66
+ # defined using the configurator
67
+ cube = OlapTest.olap_query(:category, :aggregate => :sum_int)
68
+ assert_equal 33, cube[:first_cat]
69
+ assert_equal 77, cube[:second_cat]
70
+
71
+ # using an SQL expression
72
+ cube = OlapTest.olap_query(:category, :aggregate => 'avg(olap_tests.int_field)')
73
+ assert_equal 33.0, cube[:first_cat]
74
+ assert_equal (33.0 + 44.0) / 2, cube[:second_cat]
75
+ assert_equal 33.0, cube[:no_category]
76
+ assert_equal nil, cube[:third_cat]
77
+ assert_equal nil, cube[:other]
78
+
79
+ # multiple aggregates
80
+ cube = OlapTest.olap_query(:category, :aggregate => [:count_distinct, 'avg(olap_tests.int_field)', :sum_int ])
81
+ assert_equal 1, cube.depth
82
+ assert_equal 5, cube.breadth
83
+
84
+ assert_equal 1, cube[:first_cat][:count_distinct]
85
+ assert_equal 33.0, cube[:first_cat][:sum_int]
86
+ assert_equal (33.0 + 44.0) / 2, cube[:second_cat]['avg(olap_tests.int_field)']
87
+
88
+ # array notation
89
+ cube = OlapTest.olap_query(:category, :aggregate => [:count_distinct, 'avg(olap_tests.int_field)', :sum_int] )
90
+ assert_equal 1, cube.depth
91
+ assert_equal 5, cube.breadth
92
+
93
+ assert_equal 1, cube[:first_cat][:count_distinct]
94
+ assert_equal 33.0, cube[:first_cat][:sum_int]
95
+ assert_equal (33.0 + 44.0) / 2, cube[:second_cat]['avg(olap_tests.int_field)']
96
+ end
97
+
98
+ def test_with_overlap
99
+ cube = OlapTest.olap_query(:with_overlap)
100
+ assert_active_olap_cube cube, [3]
101
+
102
+ assert_equal 2, cube[:like_23]
103
+ assert_equal 3, cube[:starts_with_1]
104
+ assert_equal 1, cube[:other]
105
+
106
+ assert cube.sum > OlapTest.count
107
+ end
108
+
109
+ def test_conditions
110
+ cube = OlapTest.olap_query(:field => :category_field, :conditions => {:datetime_field => nil})
111
+ assert_equal 1, cube.depth
112
+ assert_equal 2, cube.sum
113
+
114
+ assert_equal 1, OlapTest.olap_drilldown({:field => :category_field, :conditions => {:datetime_field => nil}} => 'second_cat').count
115
+ end
116
+
117
+ def test_config_with_lambda_trend_and_transpose
118
+
119
+ cube = OlapTest.olap_query(:category, :my_trend)
120
+ assert_equal 5, cube.breadth # 4 + other
121
+ assert_equal 2, cube.depth
122
+ assert_equal :first_cat, cube.dimension.categories.first.label
123
+
124
+ # switch the dimensions using transpose
125
+ cube = cube.transpose
126
+
127
+ assert_equal 20, cube.breadth # 20 periods
128
+ assert_equal 2, cube.depth
129
+
130
+ end
131
+
132
+ def test_with_config
133
+ cube = OlapTest.olap_query(:category)
134
+ assert_equal 1, cube[:first_cat]
135
+ assert_equal 2, cube[:second_cat]
136
+ assert_equal 0, cube[:third_cat]
137
+ assert_equal nil, cube[:fourth_cat]
138
+ assert_equal 1, cube[:no_category]
139
+ end
140
+
141
+
142
+ def test_with_periods
143
+ dimension_1 = { :trend => { :timestamp_field => :datetime_field, :period_count => 5}}
144
+ dimension_2 = :category_field
145
+
146
+ cube = OlapTest.olap_query(dimension_1, dimension_2)
147
+
148
+ assert_active_olap_cube cube, [5, :unknown]
149
+
150
+ assert_equal 1, cube[:period_2, 'first_cat']
151
+ assert_equal 0, cube[:period_2, 'second_cat']
152
+ assert_equal 0, cube[:period_0, 'first_cat']
153
+ assert_equal 1, cube[:period_0, 'second_cat']
154
+ assert_equal 0, cube[:period_3, 'second_cat']
155
+ assert_equal 0, cube[:period_1, 'first_cat']
156
+
157
+ assert_equal 0, OlapTest.olap_drilldown(dimension_1 => :period_4, dimension_2 => 'second_cat').count
158
+ end
159
+
160
+ def test_with_three_dimensions
161
+ dimension_1 = { :categories => { :datetime_field_set => 'datetime_field IS NOT NULL' } }
162
+ dimension_2 = :category_field
163
+ dimension_3 = { :categories => { :string_like_2 => ["string_field LIKE ?", '%2%'] } }
164
+
165
+ cube = OlapTest.olap_query(dimension_1, dimension_2, dimension_3)
166
+ assert_active_olap_cube cube, [2, :unknown, 2]
167
+
168
+ # check that every value is set
169
+ assert_equal 1, cube[:datetime_field_set, 'first_cat',:string_like_2]
170
+ assert_equal 0, cube[:datetime_field_set, 'first_cat',:other]
171
+ assert_equal 0, cube[:datetime_field_set, 'second_cat',:string_like_2]
172
+ assert_equal 1, cube[:datetime_field_set, 'second_cat',:other]
173
+ assert_equal 0, cube[:datetime_field_set, nil,:string_like_2]
174
+ assert_equal 0, cube[:datetime_field_set, nil,:other]
175
+ assert_equal 0, cube[:other, 'first_cat',:string_like_2]
176
+ assert_equal 0, cube[:other, 'first_cat',:other]
177
+ assert_equal 1, cube[:other, 'second_cat',:string_like_2]
178
+ assert_equal 0, cube[:other, 'second_cat',:other]
179
+ assert_equal 1, cube[:other, nil,:string_like_2]
180
+ assert_equal 0, cube[:other, nil,:other]
181
+
182
+ # checking that drilling down results in cubes as well
183
+ intermediate_cube = cube[:other]
184
+ assert_active_olap_cube intermediate_cube, [:unknown, 2]
185
+ assert_active_olap_cube cube[:other, 'second_cat'], [2]
186
+ assert_active_olap_cube cube[:other]['second_cat'], [2]
187
+
188
+ assert 1, intermediate_cube['second_cat'][:string_like_2]
189
+ assert 1, cube[:other, 'second_cat'][:string_like_2]
190
+
191
+ # check for order preservation
192
+ found_categories = []
193
+ intermediate_cube.each do |category, drilled_down_cube|
194
+ assert_active_olap_cube drilled_down_cube, [2]
195
+ found_categories << category.label
196
+ end
197
+ assert_equal ['first_cat', 'second_cat', nil], found_categories
198
+ end
199
+
200
+ def test_condition_field_with_two_dimensions
201
+ dimension_1 = { :categories => { :datetime_field_set => 'datetime_field IS NOT NULL' } }
202
+ dimension_2 = :category_field
203
+
204
+ cube = OlapTest.olap_query(dimension_1, dimension_2)
205
+ assert_active_olap_cube cube, [2, :unknown]
206
+
207
+ assert_equal 1, cube[:datetime_field_set, 'first_cat']
208
+ assert_equal 1, cube[:datetime_field_set, 'second_cat']
209
+ assert_equal 0, cube[:datetime_field_set, nil]
210
+ assert_equal 0, cube[:other, 'first_cat']
211
+ assert_equal 1, cube[:other, 'second_cat']
212
+ assert_equal 1, cube[:other, nil]
213
+
214
+ cube = OlapTest.olap_query(dimension_2, dimension_1)
215
+ assert_active_olap_cube cube, [:unknown, 2]
216
+
217
+ assert_equal 1, cube['first_cat', :datetime_field_set]
218
+ assert_equal 1, cube['second_cat', :datetime_field_set]
219
+ assert_equal 1, cube['second_cat', :other]
220
+ assert_equal 1, cube[nil, :other]
221
+ end
222
+
223
+ def test_condition_field
224
+ cube = OlapTest.olap_query(:category_field)
225
+ assert_active_olap_cube cube, [:unknown]
226
+
227
+ assert_equal 1, cube['first_cat']
228
+ assert_equal 2, cube['second_cat']
229
+ assert_equal nil, cube['third_cat']
230
+ assert_equal nil, cube['fourth_cat']
231
+ assert_equal 1, cube[nil]
232
+
233
+ assert_equal 1, OlapTest.olap_drilldown(:category_field => nil).count
234
+ end
235
+
236
+ def test_two_dimensions
237
+ dimension_1 = { :categories => { :datetime_field_not_set => {:datetime_field => nil} } }
238
+ dimension_2 = { :categories => { :string_like_2 => ["string_field LIKE ?", '%2%'] } }
239
+
240
+ cube = OlapTest.olap_query(dimension_1, dimension_2)
241
+ assert_active_olap_cube cube, [2, 2]
242
+
243
+ assert_equal 0, cube[:datetime_field_not_set,:other]
244
+ assert_equal 2, cube[:datetime_field_not_set,:string_like_2]
245
+ assert_equal 1, cube[:other,:other]
246
+ assert_equal 1, cube[:other,:string_like_2]
247
+
248
+ assert_equal 0, OlapTest.olap_drilldown(dimension_1 => :datetime_field_not_set, dimension_2 => :other).length
249
+ assert_equal 2, OlapTest.olap_drilldown(dimension_1 => :datetime_field_not_set, dimension_2 => :string_like_2).length
250
+
251
+ end
252
+
253
+ def test_two_dimensions_without_other
254
+ dimension_1 = { :categories => { :datetime_field_not_set => {:datetime_field => nil }, :other => false} }
255
+ dimension_2 = { :categories => { :string_like_2 => ["string_field LIKE ?", '%2%'], :other => false } }
256
+
257
+ cube = OlapTest.olap_query(dimension_1, dimension_2)
258
+ assert_active_olap_cube cube, [1, 1]
259
+
260
+ assert_nil cube[:other]
261
+ assert_nil cube[:datetime_field_not_set,:other]
262
+ assert_equal 2, cube[:datetime_field_not_set,:string_like_2]
263
+
264
+ end
265
+
266
+ def test_olap_query
267
+ cube = OlapTest.olap_query :categories => { :datetime_field_not_set => {:datetime_field => nil} }
268
+ assert_active_olap_cube cube, [2]
269
+ assert_equal 2, cube[:datetime_field_not_set]
270
+ assert_equal 2, cube[:other]
271
+
272
+ cube = OlapTest.olap_query :categories => { :string_like_2 => ["string_field LIKE ?", '%2%'] }
273
+ assert_active_olap_cube cube, [2]
274
+ assert_equal 3, cube[:string_like_2]
275
+ assert_equal 1, cube[:other]
276
+
277
+ found_categories = []
278
+ cube.each do |category, res|
279
+ assert_kind_of Numeric, res
280
+ found_categories << category.label
281
+ end
282
+ # cassert the correct order for the categories
283
+ assert_equal [:string_like_2, :other], found_categories
284
+ end
285
+
286
+ def test_drilldown
287
+ unsets = OlapTest.olap_drilldown({:categories => {:datetime_field_not_set => {:datetime_field => nil}}} => :datetime_field_not_set)
288
+ assert_equal 2, unsets.length
289
+
290
+ others = OlapTest.olap_drilldown({:categories => {:datetime_field_not_set => {:datetime_field => nil}}} => :other)
291
+ assert_equal 2, others.length
292
+ end
293
+
294
+ def test_olap_query_within_scope
295
+
296
+ assert_active_olap_enabled OlapTest
297
+
298
+ assert_equal 3, OlapTest.int_field_33.count
299
+ cube = OlapTest.int_field_33.olap_query :categories => { :datetime_field_not_set => {:datetime_field => nil} }
300
+ assert_active_olap_cube cube, [2]
301
+ assert_equal 1, cube[:datetime_field_not_set]
302
+ assert_equal 2, cube[:other] # the other record does not fall within the scope int_field_33
303
+
304
+ unsets = OlapTest.int_field_33.olap_drilldown({:categories => {:datetime_field_not_set => {:datetime_field => nil}}} => :datetime_field_not_set)
305
+ assert_equal 1, unsets.length
306
+
307
+ others = OlapTest.int_field_33.olap_drilldown({:categories => {:datetime_field_not_set => {:datetime_field => nil}}} => :other)
308
+ assert_equal 2, others.length
309
+ end
310
+
311
+ # the actual SQL expression strings are connection specific,
312
+ # For this test, they are in SQLite3 format
313
+ def test_other_condition
314
+ dimension = ActiveOLAP::Dimension.create(OlapTest, :categories => { :datetime_field_set => {:datetime_field => nil}})
315
+ assert_kind_of ActiveOLAP::Dimension, dimension
316
+ assert_equal '((("olap_tests"."datetime_field" IS NULL)) IS NULL OR NOT(("olap_tests"."datetime_field" IS NULL)))', dimension[:other].to_sanitized_sql
317
+
318
+ dimension = { :categories => { :datetime_field_set => {:datetime_field => nil} } }
319
+ dimension = ActiveOLAP::Dimension.create(OlapTest, dimension)
320
+ assert_kind_of String, dimension[:other].conditions
321
+
322
+ dimension = { :categories => { :other => false, :datetime_field_set => {:datetime_field => nil} } }
323
+ dimension = ActiveOLAP::Dimension.create(OlapTest, dimension)
324
+ assert_nil dimension[:other]
325
+
326
+ dimension = { :categories => { :other => nil, :datetime_field_set => {:datetime_field => nil} } }
327
+ dimension = ActiveOLAP::Dimension.create(OlapTest, dimension)
328
+ assert_nil dimension[:other]
329
+
330
+ dimension = { :categories => { :other => ['willem = ?', "grea't"], :datetime_field_set => {:datetime_field => nil} } }
331
+ dimension = ActiveOLAP::Dimension.create(OlapTest, dimension)
332
+ assert_equal ["willem = ?", "grea't"], dimension[:other].conditions
333
+ assert_equal "willem = 'grea''t'", dimension[:other].to_sanitized_sql
334
+ end
335
+ end