mochigome 0.1.13 → 0.1.14

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.
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: []