mondrian-olap 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/query_spec.rb CHANGED
@@ -101,7 +101,7 @@ describe "Query" do
101
101
  end
102
102
 
103
103
  it "should return formatted cells" do
104
- @result.formatted_values.map{|r| r.map{|s| BigDecimal.new(s.gsub(',',''))}}.should == @expected_result_values
104
+ @result.formatted_values.map{|r| r.map{|s| BigDecimal(s.gsub(',',''))}}.should == @expected_result_values
105
105
  end
106
106
 
107
107
  end
@@ -703,6 +703,11 @@ describe "Query" do
703
703
  execute
704
704
  result.values.should == sql_select_numbers(@sql_select)
705
705
  end
706
+
707
+ it "should not fail without columns" do
708
+ result = @query.rows('[Product].DefaultMember').execute
709
+ result.values.should == [[]]
710
+ end
706
711
  end
707
712
 
708
713
  describe "result HTML formatting" do
@@ -713,14 +718,6 @@ describe "Query" do
713
718
  execute
714
719
  Nokogiri::HTML.fragment(result.to_html).css('tr').size.should == (sql_select_numbers(@sql_select).size + 1)
715
720
  end
716
-
717
- # it "test" do
718
- # puts @olap.from('Sales').
719
- # columns('[Product].children').
720
- # rows('[Customers].[USA].[CA].children').
721
- # where('[Time].[2010].[Q1]', '[Measures].[Store Sales]').
722
- # execute.to_html
723
- # end
724
721
  end
725
722
 
726
723
  end
@@ -842,15 +839,6 @@ describe "Query" do
842
839
  String,
843
840
  BigDecimal
844
841
  ]
845
- when 'mssql'
846
- [
847
- Integer, String, Integer, Integer, Integer,
848
- String, String, String, String, String, String,
849
- # last one can be BigDecimal or Integer, probably depends on MS SQL version
850
- String, String, String, Numeric,
851
- String,
852
- BigDecimal
853
- ]
854
842
  else
855
843
  [
856
844
  Integer, String, Integer, Integer, Integer,
@@ -896,6 +884,25 @@ describe "Query" do
896
884
  ]
897
885
  end
898
886
 
887
+ it "should return rows also for field dimension that is not present in the report query" do
888
+ result = @olap.from('Sales').columns('[Measures].[Unit Sales]').rows('[Customers].[Canada].[BC].[Burnaby]').execute
889
+ drill_through = result.drill_through(row: 0, column: 0, return: ["[Product].[Product Family]"])
890
+ drill_through.rows.should == @sql.select_rows(<<-SQL)
891
+ SELECT
892
+ product_classes.product_family
893
+ FROM
894
+ sales,
895
+ products,
896
+ product_classes,
897
+ customers
898
+ WHERE
899
+ products.product_class_id = product_classes.id AND
900
+ sales.product_id = products.id AND
901
+ sales.customer_id = customers.id AND
902
+ customers.country = 'Canada' AND customers.state_province = 'BC' AND customers.city = 'Burnaby'
903
+ SQL
904
+ end
905
+
899
906
  it "should return only nonempty measures" do
900
907
  @drill_through = @result.drill_through(:row => 0, :column => 0,
901
908
  :return => "[Measures].[Unit Sales], [Measures].[Store Sales]",
@@ -904,7 +911,7 @@ describe "Query" do
904
911
  @drill_through.column_labels.should == [
905
912
  "Unit Sales", "Store Sales"
906
913
  ]
907
- @drill_through.rows.all?{|r| r.any?{|c| c}}.should be_true
914
+ @drill_through.rows.all?{|r| r.any?{|c| c}}.should == true
908
915
  end
909
916
 
910
917
  it "should return member name and property values" do
@@ -913,12 +920,12 @@ describe "Query" do
913
920
  "Name([Customers].[Name])",
914
921
  "Property([Customers].[Name], 'Gender')",
915
922
  "Property([Customers].[Name], 'Description')",
916
- "Property([Customers].[Name], 'Very long non-existing property name')"
923
+ "Property([Customers].[Name], 'Non-existing property name')"
917
924
  ]
918
925
  )
919
926
  @drill_through.column_labels.should == [
920
927
  "Name", "Gender", "Description",
921
- "Very long non-existing property name"[0, MONDRIAN_DRIVER == 'oracle' ? 30 : 9999]
928
+ "Non-existing property name"
922
929
  ]
923
930
  @drill_through.rows.should == @sql.select_rows(<<-SQL)
924
931
  SELECT
@@ -981,6 +988,64 @@ describe "Query" do
981
988
  end
982
989
  end
983
990
 
991
+ describe "drill through cell with return and role restrictions" do
992
+ before(:all) do
993
+ @olap.role_name = "Canada manager"
994
+ @query = @olap.from('Sales')
995
+ @result = @query.columns('[Measures].[Unit Sales]').
996
+ rows('[Customers].[All Customers]').
997
+ execute
998
+ end
999
+
1000
+ after(:all) do
1001
+ @olap.role_name = nil
1002
+ end
1003
+
1004
+ it "should return data according to role restriction" do
1005
+ @drill_through = @result.drill_through(:row => 0, :column => 0, :return => [
1006
+ '[Customers].[Country]',
1007
+ '[Measures].[Unit Sales]'
1008
+ ])
1009
+ @drill_through.rows.all? { |r| r.first == "Canada" }.should == true
1010
+ end
1011
+ end
1012
+
1013
+ describe "drill through virtual cube cell with return" do
1014
+ before(:all) do
1015
+ @query = @olap.from('Sales and Warehouse')
1016
+ @result = @query.columns(
1017
+ '[Measures].[Unit Sales]', '[Measures].[Store Sales]',
1018
+ '[Measures].[Units Shipped]', '[Measures].[Products with units shipped]'
1019
+ ).
1020
+ rows('[Product].children').
1021
+ where('[Time].[2010].[Q1]', '[Time].[2010].[Q2]').
1022
+ execute
1023
+ end
1024
+
1025
+ it "should return specified fields from other cubes as empty strings" do
1026
+ @drill_through = @result.drill_through(:row => 0, :column => 3, :return => [
1027
+ '[Time].[Month]',
1028
+ '[Product].[Product Family]',
1029
+ '[Customers].[City]', # missing in Warehouse cube
1030
+ '[Measures].[Unit Sales]', # missing in Warehouse cube
1031
+ '[Measures].[Units Shipped]',
1032
+ '[Measures].[Products with units shipped]'
1033
+ ])
1034
+ @drill_through.column_labels.should == [
1035
+ "Month (Key)",
1036
+ "Product Family (Key)",
1037
+ "City (Key)",
1038
+ "Unit Sales",
1039
+ "Units Shipped",
1040
+ "Products with units shipped"
1041
+ ]
1042
+ # Validate that only City and Unit Sales values are missing
1043
+ @drill_through.rows.map { |r| r.map(&:present?) }.uniq.should == [
1044
+ [true, true, false, false, true, true]
1045
+ ]
1046
+ end
1047
+ end
1048
+
984
1049
  describe "drill through statement" do
985
1050
  before(:all) do
986
1051
  @query = @olap.from('Sales').
data/spec/rake_tasks.rb CHANGED
@@ -5,10 +5,12 @@ namespace :db do
5
5
  require File.expand_path("../spec_helper", __FILE__)
6
6
  end
7
7
 
8
+ import_data_drivers = %w(vertica snowflake clickhouse mariadb)
9
+
8
10
  desc "Create test database tables"
9
11
  task :create_tables => :require_spec_helper do
10
12
  puts "==> Creating tables for test data"
11
- ActiveRecord::Schema.define do
13
+ ActiveRecord::Schema.instance_eval do
12
14
 
13
15
  create_table :time, :force => true do |t|
14
16
  t.datetime :the_date
@@ -34,7 +36,10 @@ namespace :db do
34
36
  t.string :product_family, :limit => 30
35
37
  end
36
38
 
37
- create_table :customers, :force => true do |t|
39
+ customers_options = {force: true}
40
+ customers_options[:id] = false if import_data_drivers.include?(MONDRIAN_DRIVER)
41
+ create_table :customers, **customers_options do |t|
42
+ t.integer :id, :limit => 8 if import_data_drivers.include?(MONDRIAN_DRIVER)
38
43
  t.string :country, :limit => 30
39
44
  t.string :state_province, :limit => 30
40
45
  t.string :city, :limit => 30
@@ -42,6 +47,7 @@ namespace :db do
42
47
  t.string :lname, :limit => 30
43
48
  t.string :fullname, :limit => 60
44
49
  t.string :gender, :limit => 30
50
+ t.date :birthdate
45
51
  t.integer :promotion_id
46
52
  t.string :related_fullname, :limit => 60
47
53
  # Mondrian does not support properties with Oracle CLOB type
@@ -79,7 +85,7 @@ namespace :db do
79
85
  execute "ALTER TABLE customers MODIFY COLUMN id BIGINT NOT NULL AUTO_INCREMENT"
80
86
  when /postgresql/
81
87
  execute "ALTER TABLE customers ALTER COLUMN id SET DATA TYPE bigint"
82
- when /mssql|sqlserver/
88
+ when /sqlserver/
83
89
  sql = "SELECT name FROM sysobjects WHERE xtype = 'PK' AND parent_obj=OBJECT_ID('customers')"
84
90
  primary_key_constraint = select_value(sql)
85
91
  execute "ALTER TABLE customers DROP CONSTRAINT #{primary_key_constraint}"
@@ -90,11 +96,23 @@ namespace :db do
90
96
  create_table :sales, :force => true, :id => false do |t|
91
97
  t.integer :product_id
92
98
  t.integer :time_id
93
- t.integer :customer_id
99
+ t.integer :customer_id, limit: MONDRIAN_DRIVER == 'sqlserver' ? nil : 8
94
100
  t.integer :promotion_id
95
- t.decimal :store_sales, :precision => 10, :scale => 4
96
- t.decimal :store_cost, :precision => 10, :scale => 4
97
- t.decimal :unit_sales, :precision => 10, :scale => 4
101
+ t.decimal :store_sales, precision: 10, scale: 4
102
+ t.decimal :store_cost, precision: 10, scale: 4
103
+ t.decimal :unit_sales, precision: 10, scale: 4
104
+ end
105
+
106
+ case MONDRIAN_DRIVER
107
+ when /sqlserver/
108
+ execute "ALTER TABLE sales ALTER COLUMN customer_id BIGINT"
109
+ end
110
+
111
+ create_table :warehouse, :force => true, :id => false do |t|
112
+ t.integer :product_id
113
+ t.integer :time_id
114
+ t.integer :units_shipped
115
+ t.decimal :store_invoice, precision: 10, scale: 4
98
116
  end
99
117
  end
100
118
  end
@@ -128,11 +146,17 @@ namespace :db do
128
146
  belongs_to :product
129
147
  belongs_to :customer
130
148
  end
149
+ class Warehouse < ActiveRecord::Base
150
+ self.table_name = "warehouse"
151
+ belongs_to :time_by_day
152
+ belongs_to :product
153
+ end
131
154
  end
132
155
 
133
156
  desc "Create test data"
134
- task :create_data => [:create_tables] + ( %w(vertica snowflake).include?(ENV['MONDRIAN_DRIVER']) ? [:import_data] :
135
- [ :create_time_data, :create_product_data, :create_promotion_data, :create_customer_data, :create_sales_data ] )
157
+ task :create_data => [:create_tables] + (import_data_drivers.include?(ENV['MONDRIAN_DRIVER']) ? [:import_data] :
158
+ [ :create_time_data, :create_product_data, :create_promotion_data, :create_customer_data, :create_sales_data,
159
+ :create_warehouse_data ] )
136
160
 
137
161
  task :create_time_data => :define_models do
138
162
  puts "==> Creating time dimension"
@@ -217,6 +241,7 @@ namespace :db do
217
241
  :lname => "Last#{i}",
218
242
  :fullname => "First#{i} Last#{i}",
219
243
  :gender => i % 2 == 0 ? "M" : "F",
244
+ :birthdate => Date.new(1970, 1, 1) + i,
220
245
  :promotion_id => promotions[i % 10].id,
221
246
  :related_fullname => "First#{i} Last#{i}",
222
247
  :description => 100.times.map{"1234567890"}.join("\n")
@@ -236,10 +261,10 @@ namespace :db do
236
261
  :related_fullname => "Big Number"
237
262
  }
238
263
  case MONDRIAN_DRIVER
239
- when /mssql|sqlserver/
240
- Customer.connection.with_identity_insert_enabled("customers") do
241
- Customer.create!(attributes)
242
- end
264
+ when 'sqlserver'
265
+ Customer.connection.execute "SET IDENTITY_INSERT customers ON"
266
+ Customer.create!(attributes)
267
+ Customer.connection.execute "SET IDENTITY_INSERT customers OFF"
243
268
  else
244
269
  Customer.create!(attributes)
245
270
  end
@@ -266,8 +291,24 @@ namespace :db do
266
291
  end
267
292
  end
268
293
 
294
+ task :create_warehouse_data => :define_models do
295
+ puts "==> Creating warehouse data"
296
+ Warehouse.delete_all
297
+ count = 100
298
+ products = Product.order("id").to_a[0...count]
299
+ times = TimeDimension.order("id").to_a[0...count]
300
+ count.times do |i|
301
+ Warehouse.create!(
302
+ :product_id => products[i].id,
303
+ :time_id => times[i].id,
304
+ :units_shipped => i+1,
305
+ :store_invoice => BigDecimal("1#{i}.1234")
306
+ )
307
+ end
308
+ end
309
+
269
310
  export_data_dir = File.expand_path("spec/support/data")
270
- table_names = %w(time product_classes products customers sales)
311
+ table_names = %w(time product_classes products customers promotions sales warehouse)
271
312
 
272
313
  desc "Export test data"
273
314
  task :export_data => :create_data do
@@ -330,13 +371,41 @@ namespace :db do
330
371
  "FILE_FORMAT = (FORMAT_NAME = csv)"
331
372
  puts "==> Loaded #{count} records"
332
373
  end
374
+
375
+ when 'clickhouse'
376
+ table_names.each do |table_name|
377
+ puts "==> Truncate #{table_name}"
378
+ conn.execute "TRUNCATE TABLE #{table_name}"
379
+ puts "==> Copy into #{table_name}"
380
+ file_path = "#{export_data_dir}/#{table_name}.csv"
381
+ columns_string = File.open(file_path) { |f| f.gets }.chomp
382
+ clickhouse_format_class = Java::com.clickhouse.data.ClickHouseFormat rescue Java::com.clickhouse.client.ClickHouseFormat
383
+ conn.jdbc_connection.createStatement.write.
384
+ query("INSERT INTO #{table_name}(#{columns_string})").
385
+ data(file_path).format(clickhouse_format_class::CSVWithNames).execute
386
+ count = conn.select_value("SELECT COUNT(*) FROM #{table_name}").to_i
387
+ puts "==> Loaded #{count} records"
388
+ end
389
+
390
+ when 'mariadb'
391
+ table_names.each do |table_name|
392
+ puts "==> Truncate #{table_name}"
393
+ conn.execute "TRUNCATE TABLE `#{table_name}`"
394
+ puts "==> Copy into #{table_name}"
395
+ file_path = "#{export_data_dir}/#{table_name}.csv"
396
+ columns_string = File.open(file_path) { |f| f.gets }.chomp
397
+ count = conn.execute "LOAD DATA LOCAL INFILE '#{file_path}' INTO TABLE `#{table_name}` CHARACTER SET UTF8 " \
398
+ "FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' IGNORE 1 LINES (#{columns_string})"
399
+ puts "==> Loaded #{count} records"
400
+ end
401
+
333
402
  end
334
403
  end
335
404
 
336
405
  end
337
406
 
338
407
  namespace :spec do
339
- %w(mysql jdbc_mysql postgresql oracle mssql sqlserver vertica snowflake).each do |driver|
408
+ %w(mysql jdbc_mysql postgresql oracle sqlserver vertica snowflake clickhouse mariadb).each do |driver|
340
409
  desc "Run specs with #{driver} driver"
341
410
  task driver do
342
411
  ENV['MONDRIAN_DRIVER'] = driver
@@ -347,7 +416,7 @@ namespace :spec do
347
416
 
348
417
  desc "Run specs with all primary database drivers"
349
418
  task :all do
350
- %w(mysql jdbc_mysql postgresql oracle mssql).each do |driver|
419
+ %w(mysql jdbc_mysql postgresql oracle sqlserver).each do |driver|
351
420
  Rake::Task["spec:#{driver}"].invoke
352
421
  end
353
422
  end
@@ -865,241 +865,6 @@ describe "Schema definition" do
865
865
  end
866
866
  end
867
867
 
868
- describe "User defined functions and formatters in JavaScript" do
869
- next pending "not supported by Mondrian in Java 8" if ENV_JAVA["java.version"] >= "1.8"
870
-
871
- before(:each) do
872
- @schema.define do
873
- cube 'Sales' do
874
- table 'sales'
875
- dimension 'Customers', :foreign_key => 'customer_id' do
876
- hierarchy :has_all => true, :all_member_name => 'All Customers', :primary_key => 'id' do
877
- table 'customers'
878
- level 'Name', :column => 'fullname' do
879
- member_formatter { javascript "return member.getName().toUpperCase();" }
880
- property 'City', :column => 'city' do
881
- property_formatter { javascript "return propertyValue.toUpperCase();" }
882
- end
883
- end
884
- end
885
- end
886
- calculated_member 'Factorial' do
887
- dimension 'Measures'
888
- formula 'Factorial(6)'
889
- cell_formatter do
890
- javascript <<-JS
891
- var s = value.toString();
892
- while (s.length < 20) {
893
- s = "0" + s;
894
- }
895
- return s;
896
- JS
897
- end
898
- end
899
- calculated_member 'City' do
900
- dimension 'Measures'
901
- formula "[Customers].CurrentMember.Properties('City')"
902
- end
903
- end
904
- user_defined_function 'Factorial' do
905
- javascript <<-JS
906
- function getParameterTypes() {
907
- return new Array(
908
- new mondrian.olap.type.NumericType());
909
- }
910
- function getReturnType(parameterTypes) {
911
- return new mondrian.olap.type.NumericType();
912
- }
913
- function execute(evaluator, arguments) {
914
- var n = arguments[0].evaluateScalar(evaluator);
915
- return factorial(n);
916
- }
917
- function factorial(n) {
918
- return n <= 1 ? 1 : n * factorial(n - 1);
919
- }
920
- JS
921
- end
922
- end
923
- @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema)
924
- end
925
-
926
- it "should render XML" do
927
- @schema.to_xml.should be_like <<-XML
928
- <?xml version="1.0" encoding="UTF-8"?>
929
- <Schema name="default">
930
- <Cube name="Sales">
931
- <Table name="sales"/>
932
- <Dimension foreignKey="customer_id" name="Customers">
933
- <Hierarchy allMemberName="All Customers" hasAll="true" primaryKey="id">
934
- <Table name="customers"/>
935
- <Level column="fullname" name="Name" uniqueMembers="true">
936
- <MemberFormatter>
937
- <Script language="JavaScript">return member.getName().toUpperCase();</Script>
938
- </MemberFormatter>
939
- <Property column="city" name="City">
940
- <PropertyFormatter>
941
- <Script language="JavaScript">return propertyValue.toUpperCase();</Script>
942
- </PropertyFormatter>
943
- </Property>
944
- </Level>
945
- </Hierarchy>
946
- </Dimension>
947
- <CalculatedMember dimension="Measures" name="Factorial">
948
- <Formula>Factorial(6)</Formula>
949
- <CellFormatter>
950
- <Script language="JavaScript">
951
- var s = value.toString();
952
- while (s.length &lt; 20) {
953
- s = "0" + s;
954
- }
955
- return s;
956
- </Script>
957
- </CellFormatter>
958
- </CalculatedMember>
959
- <CalculatedMember dimension="Measures" name="City">
960
- <Formula>[Customers].CurrentMember.Properties('City')</Formula>
961
- </CalculatedMember>
962
- </Cube>
963
- <UserDefinedFunction name="Factorial">
964
- <Script language="JavaScript">
965
- function getParameterTypes() {
966
- return new Array(
967
- new mondrian.olap.type.NumericType());
968
- }
969
- function getReturnType(parameterTypes) {
970
- return new mondrian.olap.type.NumericType();
971
- }
972
- function execute(evaluator, arguments) {
973
- var n = arguments[0].evaluateScalar(evaluator);
974
- return factorial(n);
975
- }
976
- function factorial(n) {
977
- return n &lt;= 1 ? 1 : n * factorial(n - 1);
978
- }
979
- </Script>
980
- </UserDefinedFunction>
981
- </Schema>
982
- XML
983
- end
984
-
985
- it "should execute user defined function" do
986
- result = @olap.from('Sales').columns('[Measures].[Factorial]').execute
987
- value = 1*2*3*4*5*6
988
- result.values.should == [value]
989
- result.formatted_values.should == ["%020d" % value]
990
- end
991
-
992
- it "should format members and properties" do
993
- result = @olap.from('Sales').columns('[Measures].[City]').rows('[Customers].[All Customers].Children').execute
994
- result.row_members.each_with_index do |member, i|
995
- member.caption.should == member.name.upcase
996
- city = member.property_value('City')
997
- result.formatted_values[i].first.should == city
998
- member.property_formatted_value('City').should == city.upcase
999
- end
1000
- end
1001
- end
1002
-
1003
- describe "User defined functions and formatters in CoffeeScript" do
1004
- next pending "not supported by Mondrian in Java 8" if ENV_JAVA["java.version"] >= "1.8"
1005
-
1006
- before(:each) do
1007
- @schema.define do
1008
- cube 'Sales' do
1009
- table 'sales'
1010
- dimension 'Customers', :foreign_key => 'customer_id' do
1011
- hierarchy :has_all => true, :all_member_name => 'All Customers', :primary_key => 'id' do
1012
- table 'customers'
1013
- level 'Name', :column => 'fullname' do
1014
- member_formatter { coffeescript "member.getName().toUpperCase()" }
1015
- property 'City', :column => 'city' do
1016
- property_formatter { coffeescript "propertyValue.toUpperCase()" }
1017
- end
1018
- end
1019
- end
1020
- end
1021
- calculated_member 'Factorial' do
1022
- dimension 'Measures'
1023
- formula 'Factorial(6)'
1024
- cell_formatter do
1025
- coffeescript <<-CS
1026
- s = value.toString()
1027
- s = "0" + s while s.length < 20
1028
- s
1029
- CS
1030
- end
1031
- end
1032
- calculated_member 'City' do
1033
- dimension 'Measures'
1034
- formula "[Customers].CurrentMember.Properties('City')"
1035
- end
1036
- end
1037
- user_defined_function 'Factorial' do
1038
- coffeescript <<-CS
1039
- parameters: ["Numeric"]
1040
- returns: "Numeric"
1041
- execute: (n) ->
1042
- if n <= 1 then 1 else n * @execute(n - 1)
1043
- CS
1044
- end
1045
- user_defined_function 'UpperName' do
1046
- coffeescript <<-CS
1047
- parameters: ["Member"]
1048
- returns: "String"
1049
- syntax: "Property"
1050
- execute: (member) ->
1051
- member.getName().toUpperCase()
1052
- CS
1053
- end
1054
- user_defined_function 'toUpperName' do
1055
- coffeescript <<-CS
1056
- parameters: ["Member", "String"]
1057
- returns: "String"
1058
- syntax: "Method"
1059
- execute: (member, dummy) ->
1060
- member.getName().toUpperCase()
1061
- CS
1062
- end
1063
- end
1064
- @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema)
1065
- end
1066
-
1067
- it "should execute user defined function" do
1068
- result = @olap.from('Sales').columns('[Measures].[Factorial]').execute
1069
- value = 1*2*3*4*5*6
1070
- result.values.should == [value]
1071
- result.formatted_values.should == ["%020d" % value]
1072
- end
1073
-
1074
- it "should format members and properties" do
1075
- result = @olap.from('Sales').columns('[Measures].[City]').rows('[Customers].[All Customers].Children').execute
1076
- result.row_members.each_with_index do |member, i|
1077
- member.caption.should == member.name.upcase
1078
- city = member.property_value('City')
1079
- result.formatted_values[i].first.should == city
1080
- member.property_formatted_value('City').should == city.upcase
1081
- end
1082
- end
1083
-
1084
- it "should execute user defined property on member" do
1085
- result = @olap.from('Sales').
1086
- with_member('[Measures].[Upper Name]').as('[Customers].CurrentMember.UpperName').
1087
- columns('[Measures].[Upper Name]').rows('[Customers].Children').execute
1088
- result.row_members.each_with_index do |member, i|
1089
- result.values[i].should == [member.name.upcase]
1090
- end
1091
- end
1092
-
1093
- it "should execute user defined method on member" do
1094
- result = @olap.from('Sales').
1095
- with_member('[Measures].[Upper Name]').as("[Customers].CurrentMember.toUpperName('dummy')").
1096
- columns('[Measures].[Upper Name]').rows('[Customers].Children').execute
1097
- result.row_members.each_with_index do |member, i|
1098
- result.values[i].should == [member.name.upcase]
1099
- end
1100
- end
1101
- end
1102
-
1103
868
  describe "User defined functions and formatters in Ruby" do
1104
869
  before(:each) do
1105
870
  @schema.define do