mochigome 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
data/TODO CHANGED
@@ -6,3 +6,4 @@
6
6
  - Some kind of single-page preview on the edit screen would be cool. Maybe use FOP with fake data and the PNG output option?
7
7
  - Automatically set default to 0 on sum and count aggregation
8
8
  - Treat through-associations as hints for preferred paths
9
+ - Better handling of nil in subgroup fields
data/lib/mochigome_ver.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mochigome
2
- VERSION = "0.1.13"
2
+ VERSION = "0.1.14"
3
3
  end
@@ -96,6 +96,9 @@ module Mochigome
96
96
  # for this kind of stuff and also put the standard aggregation functions
97
97
  # in there?
98
98
 
99
+ # FIXME All this lambda{|t| stuff is just needlessly confusing for
100
+ # the little good that it accomplishes.
101
+
99
102
  def self.null_unless(pred, value_func)
100
103
  case_expr(
101
104
  lambda {|t| pred.call(value_func.call(t))},
@@ -114,6 +117,28 @@ module Mochigome
114
117
  }
115
118
  end
116
119
 
120
+ def self.multi_case_expr(cond_results, else_val = nil)
121
+ lambda {|t|
122
+ Arel::Nodes::SqlLiteral.new(
123
+ "(CASE " +
124
+ cond_results.map{|cond, result|
125
+ "WHEN #{arel_exprify(cond, t)} THEN #{arel_exprify(result, t)}"
126
+ } +
127
+ (else_val ? "ELSE #{arel_exprify(else_val, t)}" : "") +
128
+ "END)"
129
+ )
130
+ }
131
+ end
132
+
133
+ def self.sql_bool_to_string(attr, prefix = "")
134
+ case_expr(
135
+ Arel::Nodes::NamedFunction.new('lower', [attr]).
136
+ in(["true", "t", 1, "1", "y", "yes"]),
137
+ "#{prefix}Yes",
138
+ "#{prefix}No"
139
+ )
140
+ end
141
+
117
142
  private
118
143
 
119
144
  def self.arel_exprify(e, t = nil)
@@ -8,10 +8,15 @@ module Mochigome
8
8
  def initialize(model, attr)
9
9
  @model = model
10
10
  @attr = attr
11
- if @model.mochigome_focus_settings
12
- s = @model.mochigome_focus_settings
13
- # @attr_expr will just be nil if there's no custom subgroup expr here
11
+ s = @model.mochigome_focus_settings
12
+ if s && s.options[:custom_subgroup_exprs][attr]
14
13
  @attr_expr = s.options[:custom_subgroup_exprs][attr]
14
+ elsif @model.columns_hash[@attr.to_s].try(:type) == :boolean
15
+ @attr_expr = Mochigome::sql_bool_to_string(
16
+ model.arel_table[@attr], "#{human_name.titleize}: "
17
+ ).call(model.arel_table)
18
+ else
19
+ @attr_expr = nil
15
20
  end
16
21
  @focus_settings = Mochigome::ReportFocusSettings.new(@model)
17
22
  @focus_settings.type_name "#{@model.human_name} #{@attr.to_s.humanize}"
@@ -23,7 +28,8 @@ module Mochigome
23
28
  end
24
29
 
25
30
  def human_name
26
- "#{@model.human_name} #{@attr.to_s.humanize}"
31
+ # Get rid of duplicate words (i.e. School$school_type)
32
+ "#{@model.human_name} #{@attr.to_s.humanize}".split.map(&:downcase).uniq.join(" ")
27
33
  end
28
34
 
29
35
  def real_model?
@@ -2,3 +2,4 @@ test:
2
2
  adapter: mysql2
3
3
  database: "mochi_test"
4
4
  username: root
5
+ password: root
@@ -24,6 +24,7 @@ class CreateTables < ActiveRecord::Migration
24
24
  t.date :birth_date
25
25
  t.string :phone_number
26
26
  t.string :email_address
27
+ t.boolean :is_awesome
27
28
  t.timestamps
28
29
  end
29
30
 
data/test/factories.rb CHANGED
@@ -21,6 +21,7 @@ FactoryGirl.define do
21
21
  birth_date { 30.years.ago }
22
22
  phone_number "800-555-1212"
23
23
  email_address { "#{first_name}.#{last_name}@example.com".downcase }
24
+ is_awesome false
24
25
  end
25
26
 
26
27
  factory :store_product do
@@ -15,7 +15,8 @@ describe Mochigome::Query do
15
15
  @john = create(:owner, :first_name => "John", :last_name => "Smith")
16
16
  @store_x = create(:store, :name => "John's Store", :owner => @john)
17
17
 
18
- @jane = create(:owner, :first_name => "Jane", :last_name => "Doe")
18
+ @jane = create(:owner, :first_name => "Jane", :last_name => "Doe",
19
+ :is_awesome => true)
19
20
  @store_y = create(:store, :name => "Jane's Store (North)", :owner => @jane)
20
21
  @store_z = create(:store, :name => "Jane's Store (South)", :owner => @jane)
21
22
 
@@ -180,6 +181,18 @@ describe Mochigome::Query do
180
181
  assert_equal "Product A", (data_node/1/0/0/0).name
181
182
  end
182
183
 
184
+ it "can subgroup layers by boolean attributes" do
185
+ q = Mochigome::Query.new(
186
+ [Mochigome::SubgroupModel.new(Owner, :is_awesome), Owner, Store, Product]
187
+ )
188
+ data_node = q.run
189
+ assert_equal "Owner Is Awesome: No", (data_node/0).name
190
+ assert_equal "John Smith", (data_node/0/0).name
191
+ assert_equal "John's Store", (data_node/0/0/0).name
192
+ assert_equal "Product A", (data_node/0/0/0/0).name
193
+ assert_equal "Owner Is Awesome: Yes", (data_node/1).name
194
+ end
195
+
183
196
  it "can subgroup layers by attributes without including layer model" do
184
197
  q = Mochigome::Query.new(
185
198
  [Mochigome::SubgroupModel.new(Owner, :last_name)],
@@ -247,7 +260,7 @@ describe Mochigome::Query do
247
260
  # Store X, Product C
248
261
  assert_equal "Product C", (data_node/0/0/1).name
249
262
  assert_equal 3, (data_node/0/0/1)['Sales count']
250
- assert_equal (3*@product_c.price).to_s, (data_node/0/0/1)['Gross'].to_s
263
+ assert_equal (3*@product_c.price).to_f.to_s, (data_node/0/0/1)['Gross'].to_f.to_s
251
264
  # Store Z, Product C
252
265
  assert_equal "Product C", (data_node/1/1/0).name
253
266
  assert_equal 2, (data_node/1/1/0)['Sales count']
@@ -259,7 +272,7 @@ describe Mochigome::Query do
259
272
  # Store Z, Product C
260
273
  assert_equal "Product C", (data_node/1/0/0).name
261
274
  assert_equal 2, (data_node/1/0/0)['Sales count']
262
- assert_equal (2*@product_c.price).to_s, (data_node/1/0/0)['Gross'].to_s
275
+ assert_equal (2*@product_c.price).to_f.to_s, (data_node/1/0/0)['Gross'].to_f.to_s
263
276
  end
264
277
 
265
278
  it "collects aggregate data in subgroups" do
@@ -369,8 +382,8 @@ describe Mochigome::Query do
369
382
  data_node = q.run()
370
383
  assert_equal "John's Store", (data_node/0/0).name
371
384
  assert_equal 8, (data_node/0/0)['Sales count']
372
- assert_equal (5*@product_a.price + 3*@product_c.price).to_s,
373
- (data_node/0/0)['Gross'].to_s
385
+ assert_equal (5*@product_a.price + 3*@product_c.price).to_f.to_s,
386
+ (data_node/0/0)['Gross'].to_f.to_s
374
387
  end
375
388
 
376
389
  it "can do conditional counts" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mochigome
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 13
10
- version: 0.1.13
9
+ - 14
10
+ version: 0.1.14
11
11
  platform: ruby
12
12
  authors:
13
13
  - David Mike Simon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-27 00:00:00 Z
18
+ date: 2012-06-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -28,10 +28,10 @@ dependencies:
28
28
  - 2
29
29
  - 1
30
30
  version: "2.1"
31
- requirement: *id001
32
- prerelease: false
33
31
  type: :runtime
32
+ requirement: *id001
34
33
  name: arel
34
+ prerelease: false
35
35
  - !ruby/object:Gem::Dependency
36
36
  version_requirements: &id002 !ruby/object:Gem::Requirement
37
37
  none: false
@@ -42,10 +42,10 @@ dependencies:
42
42
  segments:
43
43
  - 0
44
44
  version: "0"
45
- requirement: *id002
46
- prerelease: false
47
45
  type: :runtime
46
+ requirement: *id002
48
47
  name: ruport
48
+ prerelease: false
49
49
  - !ruby/object:Gem::Dependency
50
50
  version_requirements: &id003 !ruby/object:Gem::Requirement
51
51
  none: false
@@ -56,10 +56,10 @@ dependencies:
56
56
  segments:
57
57
  - 0
58
58
  version: "0"
59
- requirement: *id003
60
- prerelease: false
61
59
  type: :runtime
60
+ requirement: *id003
62
61
  name: nokogiri
62
+ prerelease: false
63
63
  - !ruby/object:Gem::Dependency
64
64
  version_requirements: &id004 !ruby/object:Gem::Requirement
65
65
  none: false
@@ -70,10 +70,10 @@ dependencies:
70
70
  segments:
71
71
  - 0
72
72
  version: "0"
73
- requirement: *id004
74
- prerelease: false
75
73
  type: :runtime
74
+ requirement: *id004
76
75
  name: rgl
76
+ prerelease: false
77
77
  - !ruby/object:Gem::Dependency
78
78
  version_requirements: &id005 !ruby/object:Gem::Requirement
79
79
  none: false
@@ -84,10 +84,10 @@ dependencies:
84
84
  segments:
85
85
  - 0
86
86
  version: "0"
87
- requirement: *id005
88
- prerelease: false
89
87
  type: :runtime
88
+ requirement: *id005
90
89
  name: activerecord
90
+ prerelease: false
91
91
  description: Report generator that graphs over ActiveRecord associations
92
92
  email: david.mike.simon@gmail.com
93
93
  executables: []