Permalink
Browse files

specs around the iteration over all regions in the dimension space

  • Loading branch information...
mccraigmccraig committed Mar 23, 2012
1 parent bc59ffe commit 2a6046281c26aca6bef37b3e304deb0d8c210bcb
Showing with 122 additions and 14 deletions.
  1. +3 −3 lib/mdquery/dsl.rb
  2. +5 −5 lib/mdquery/model.rb
  3. +3 −3 spec/mdquery/dsl_spec.rb
  4. +108 −0 spec/mdquery/model_spec.rb
  5. +3 −3 spec/mdquery_spec.rb
View
@@ -135,8 +135,8 @@ class DatasetDSL
# define the datasource for the Dataset
# * +scope+ an ActiveRecord scope, used as the basis for all region queries
def source(scope)
- raise "source already set" if @source_scope
- @source_scope = scope
+ raise "source already set" if @source
+ @source = scope
end
# define a Dimension
@@ -166,7 +166,7 @@ def initialize(&proc)
def build
ds = @dimensions.map{|d| d.send(:build)}
ms = @measures.map{|m| m.send(:build)}
- MDQuery::Model::DatasetModel.new(:source_scope=>@source_scope,
+ MDQuery::Model::DatasetModel.new(:source=>@source,
:dimension_models=>ds,
:measure_models=>ms)
end
View
@@ -191,17 +191,17 @@ def do_cast(value)
end
class DatasetModel
- attr_reader :source_scope
+ attr_reader :source
attr_reader :dimension_models
attr_reader :measure_models
def initialize(attrs)
- MDQuery::Util.assign_attributes(self, attrs, [:source_scope, :dimension_models, :measure_models])
+ MDQuery::Util.assign_attributes(self, attrs, [:source, :dimension_models, :measure_models])
validate
end
def validate
- raise "no source scope!" if !source_scope
+ raise "no source!" if !source
raise "no dimension_models!" if !dimension_models || dimension_models.empty?
raise "no measure_models!" if !measure_models || measure_models.empty?
end
@@ -269,12 +269,12 @@ def analyse
data = []
with_regions do |region_segment_models|
- q = construct_query(source_scope, region_segment_models, measures)
+ q = construct_query(source, region_segment_models, measures)
points = extract(q.all, region_segment_models, measure_models)
data += points
end
- ds = dimension_models.reduce({}){|h,dm| h[dm.key] = dm.dimension(source_scope) ; h}
+ ds = dimension_models.reduce({}){|h,dm| h[dm.key] = dm.dimension(source) ; h}
MDQuery::Dataset::Dataset.new(:model=>self,
:dimensions=>ds,
View
@@ -108,10 +108,10 @@ module MDQuery::DSL
describe DatasetDSL do
it "should build a DatasetModel with multiple dimensions and measures" do
- source_scope = Object.new
+ source = Object.new
dsl = DatasetDSL.new do
- source source_scope
+ source source
dimension :foo do
segment :foo_a do
@@ -130,7 +130,7 @@ module MDQuery::DSL
end
ds = dsl.send(:build)
- ds.source_scope.should == source_scope
+ ds.source.should == source
ds.dimension_models.count.should == 2
ds.dimension_models[0].key.should == :foo
ds.dimension_models[1].key.should == :bar
View
@@ -1,5 +1,6 @@
require File.expand_path('../../spec_helper', __FILE__)
require 'mdquery/model'
+require 'set'
module MDQuery
module Model
@@ -298,6 +299,113 @@ def create(attrs={})
end
describe DatasetModel do
+ describe "region_segment_model_indexes" do
+
+ it "should produce the cross-producton of dimension segment indexes for one dimension" do
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim1],
+ :measure_models=>[mm1])
+
+ dm.region_segment_model_indexes.to_set.should == [[0],[1]].to_set
+ end
+
+ it "should produce the cross-product of dimension segment indexes for two dimensions" do
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new])
+ dim2 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new, Object.new])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim1, dim2],
+ :measure_models=>[mm1])
+
+ dm.region_segment_model_indexes.to_set.should == [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]].to_set
+ end
+
+ it "should produce the cross-product of dimension segment indexes for 3 dimensions" do
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new])
+ dim2 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new, Object.new])
+ dim3 = DimensionModel.new(:key=>:foo, :segment_models=>[Object.new, Object.new])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim1, dim2, dim3],
+ :measure_models=>[mm1])
+
+ dm.region_segment_model_indexes.to_set.should == [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[0,2,0],[0,2,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1],[1,2,0],[1,2,1]].to_set
+ end
+ end
+
+ describe "all_dimension_segment_models" do
+ it "should return a list lists of dimension segments" do
+ dim1sm1 = Object.new
+ dim1sm2 = Object.new
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[dim1sm1, dim1sm2])
+ dim2sm1 = Object.new
+ dim2sm2 = Object.new
+ dim2sm3 = Object.new
+ dim2 = DimensionModel.new(:key=>:foo, :segment_models=>[dim2sm1, dim2sm2, dim2sm3])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim1, dim2],
+ :measure_models=>[mm1])
+ dm.all_dimension_segment_models.should == [[dim1sm1, dim1sm2], [dim2sm1, dim2sm2, dim2sm3]]
+ end
+ end
+
+ describe "region_segment_models" do
+ it "should produce a list of dimension segment models corresponding to the supplied indexes" do
+ dim0sm0 = Object.new
+ dim0sm1 = Object.new
+ dim0 = DimensionModel.new(:key=>:foo, :segment_models=>[dim0sm0, dim0sm1])
+ dim1sm0 = Object.new
+ dim1sm1 = Object.new
+ dim1sm2 = Object.new
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[dim1sm0, dim1sm1, dim1sm2])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim0, dim1],
+ :measure_models=>[mm1])
+ dm.region_segment_models([0,1]).should == [dim0sm0, dim1sm1]
+ dm.region_segment_models([1,2]).should == [dim0sm1, dim1sm2]
+ end
+ end
+
+ describe "with_regions" do
+ it "should iterate of all regions calling the proc with the region segment models" do
+ dim0sm0 = Object.new
+ dim0sm1 = Object.new
+ dim0 = DimensionModel.new(:key=>:foo, :segment_models=>[dim0sm0, dim0sm1])
+ dim1sm0 = Object.new
+ dim1sm1 = Object.new
+ dim1sm2 = Object.new
+ dim1 = DimensionModel.new(:key=>:foo, :segment_models=>[dim1sm0, dim1sm1, dim1sm2])
+ mm1 = MeasureModel.new(:key=>:count, :definition=>"count(*)")
+
+ dm = DatasetModel.new(:source=>Object.new,
+ :dimension_models=>[dim0, dim1],
+ :measure_models=>[mm1])
+
+ all_region_segment_models = [[dim0sm0,dim1sm0],[dim0sm0,dim1sm1],[dim0sm0,dim1sm2],[dim0sm1,dim1sm0],[dim0sm1,dim1sm1],[dim0sm1,dim1sm2]].to_set
+ dm.with_regions do |region_segment_models|
+ all_region_segment_models.delete(region_segment_models)
+ end
+ all_region_segment_models.empty?.should == true
+ end
+ end
+
+ describe "construct_query" do
+ end
+
+ describe "extract" do
+ end
+
+ describe "analyse" do
+ end
end
end
end
View
@@ -3,10 +3,10 @@
describe "MDQuery" do
it "should use the DSL to define a Dataset" do
- source_scope = Object.new
+ source = Object.new
ds = MDQuery.dataset do
- source source_scope
+ source source
dimension :foo do
segment :foo_a do
@@ -24,7 +24,7 @@
measure :avg, "avg(foo)"
end
- ds.source_scope.should == source_scope
+ ds.source.should == source
ds.dimension_models.count.should == 2
ds.dimension_models[0].key.should == :foo
ds.dimension_models[1].key.should == :bar

0 comments on commit 2a60462

Please sign in to comment.