compendium 1.0.4 → 1.0.5

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODBjOTg1ZGM3NjVhYTM3ZjcxZDM5YjMyYjI1M2I2MzJjYTkzZmFiNg==
4
+ OWQyNzhiZThjMTNmZGNiNTg1NzY1YzlhMGUwOGM1ZDllOGU1YzhkYQ==
5
5
  data.tar.gz: !binary |-
6
- Yzg1ZDk0MmUxYTlkMDg2NTgzYTIxMzEyZjk3NjcxYjYwMzc2ZjhiZQ==
6
+ NWIyNjQ5YzBjMWI4YTZjMWNjOTEzMmExM2U3OTE5NTI5NTUyYzI0ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTA4YTdjYjUwOWE5ZTU3ODVhZmRhMzU2NjViZjZiMGFjZjk3ZDhkYjY0MjIz
10
- NjY3ZmVjODkzNGYyNWNiNDY2ODlmZWNiNTI4NGI2MGFhNGIzNThjMzgwZjZl
11
- ZTM5MzIzNjVlNDdmY2FiN2U2MTAxZTQwN2Q0NWUxZmFmN2Q2MjM=
9
+ OWMxY2NjZDlhYmNjMzliNTJjMjE3N2Y3N2EyMmNmNjQ5Nzc3ZWYwZWIwYjli
10
+ NjBlYTNlMTRlNzRmZDg3NjdjNTUxNmM5NTZhODhhNGFmZjk0ZTg4MTkwMzBi
11
+ NjMyZDgyZWM5NjUxOWRmYTg4N2UzMjFlNWM0ZGExOTRiZTRiZjE=
12
12
  data.tar.gz: !binary |-
13
- N2QyNWI2OGU4ZGQ0OWJiODMxZDNhOTA4NDU1NTliOTViNzAxMzQ3MGRlZTAz
14
- Y2UxODhjMjUyZTEzNjFhYmI5MzkwZGI3ZTYzNzEwMWM4NWVmNGVlZjJmYjdh
15
- NTZkYWJkODVmYzk4OTUzZTVhNjkxNDVjODhjN2QyNmY2N2Q4ZTM=
13
+ ZWI0OGNlYTkzNmQ2MDQ5ZGE4ZmM0NWY5NmRlZDU0NjNhNzgwNzFkMDI3MjA4
14
+ OTFkOGZhYzY0ZWZiYWNkMjY0ZDVjMjlmMzJkM2EwYTEzN2NkYTAxNzM5NzA0
15
+ MDA1Njk3ZDQ5NjAxNWRmNTdkZWE2NWM4NDVhMGE2YzE3ZmNhZDc=
@@ -14,6 +14,7 @@ div.metrics
14
14
  text-align: center;
15
15
  color: #575757;
16
16
  @include border-radius(10px);
17
+ vertical-align: middle;
17
18
 
18
19
  .metric-label
19
20
  {
@@ -31,6 +32,7 @@ div.metrics
31
32
  font-size: 600%;
32
33
  font-weight: bold;
33
34
  color: black;
35
+ line-height: 57px;
34
36
 
35
37
  .metric-data-inner
36
38
  {
@@ -86,6 +88,7 @@ div.metrics
86
88
  .metric-data
87
89
  {
88
90
  top: -10px;
91
+ line-height: 140px;
89
92
  }
90
93
  }
91
94
  }
@@ -34,11 +34,18 @@ module Compendium
34
34
  def metric(name, *args, &block)
35
35
  proc = args.first.is_a?(Proc) ? args.first : block
36
36
  opts = args.extract_options!
37
- raise ArgumentError, 'through option must be specified for metric' unless opts.key?(:through)
38
37
 
39
- [opts.delete(:through)].flatten.each do |query|
40
- raise ArgumentError, "query #{query} is not defined" unless queries.key?(query)
41
- queries[query].add_metric(name, proc, opts)
38
+ if opts.key?(:through)
39
+ [opts.delete(:through)].flatten.each do |query|
40
+ raise ArgumentError, "query #{query} is not defined" unless queries.key?(query)
41
+ queries[query].add_metric(name, proc, opts)
42
+ end
43
+ else
44
+ # Allow metrics to define queries implicitly
45
+ # ie. if you need a metric that counts a column, there's no need to explicitly create a query
46
+ # and just pass it into a metric
47
+ query = define_query("__metric_#{name}", {}, &block)
48
+ query.add_metric(name, -> result { result.first }, opts)
42
49
  end
43
50
  end
44
51
 
@@ -91,6 +98,7 @@ module Compendium
91
98
 
92
99
  metrics[name] = opts[:metric] if opts.key?(:metric)
93
100
  queries << query
101
+ query
94
102
  end
95
103
 
96
104
  def add_params_validations(name, validations)
@@ -58,16 +58,16 @@ module Compendium
58
58
  self.context = context
59
59
  self.results = {}
60
60
 
61
- only = options.delete(:only)
62
- except = options.delete(:except)
61
+ only = [options.delete(:only)].flatten.compact
62
+ except = [options.delete(:except)].flatten.compact
63
63
 
64
- raise ArgumentError, 'cannot specify only and except options at the same time' if only && except
65
- ([only] + [except]).flatten.compact.each { |q| raise ArgumentError, 'invalid query #{q}' unless queries.include?(q) }
64
+ raise ArgumentError, 'cannot specify only and except options at the same time' if !only.empty? and !except.empty?
65
+ (only + except).flatten.each { |q| raise ArgumentError, "invalid query #{q}" unless queries.include?(q) }
66
66
 
67
- queries_to_run = if only
68
- queries.slice(only)
69
- elsif except
70
- queries.except(except)
67
+ queries_to_run = if !only.empty?
68
+ queries.slice(*only)
69
+ elsif !except.empty?
70
+ queries.except(*except)
71
71
  else
72
72
  queries
73
73
  end
@@ -9,8 +9,12 @@ module Compendium
9
9
  alias :all :records
10
10
 
11
11
  def initialize(records)
12
- @records = records.map do |r|
13
- r.respond_to?(:with_indifferent_access) ? r.with_indifferent_access : r
12
+ @records = if records.respond_to?(:map)
13
+ records.map do |r|
14
+ r.respond_to?(:with_indifferent_access) ? r.with_indifferent_access : r
15
+ end
16
+ else
17
+ [records]
14
18
  end
15
19
 
16
20
  @records = Hash[@records] if records.is_a?(Hash)
@@ -13,13 +13,16 @@ module Compendium
13
13
  private
14
14
 
15
15
  def collect_results(context, params)
16
- args = collect_through_query_results(params, context)
16
+ results = collect_through_query_results(params, context)
17
17
 
18
18
  # If none of the through queries have any results, we shouldn't try to execute the query, because it
19
19
  # depends on the results of its parents.
20
- return @results = ResultSet.new([]) if args.compact.empty?
20
+ return @results = ResultSet.new([]) if results.compact.empty?
21
21
 
22
- super(context, args)
22
+ # If the proc collects two arguments, pass results and params, otherwise just results
23
+ args = !proc || proc.arity == 1 ? [results] : [results, params]
24
+
25
+ super(context, *args)
23
26
  end
24
27
 
25
28
  def fetch_results(command)
@@ -33,7 +36,7 @@ module Compendium
33
36
 
34
37
  queries.each do |q|
35
38
  q.run(params, context) unless q.ran?
36
- results[q.name] = q.results.records
39
+ results[q.name] = q.results.records.dup
37
40
  end
38
41
 
39
42
  results = results[queries.first.name] if queries.size == 1
@@ -1,3 +1,3 @@
1
1
  module Compendium
2
- VERSION = "1.0.4"
2
+ VERSION = "1.0.5"
3
3
  end
data/spec/dsl_spec.rb CHANGED
@@ -129,25 +129,33 @@ describe Compendium::DSL do
129
129
  subject.queries[:test].metrics.first.command.should == metric_proc
130
130
  end
131
131
 
132
- it "should raise an error if through is not specified" do
133
- expect{ subject.metric :test_metric, metric_proc }.to raise_error ArgumentError, 'through option must be specified for metric'
134
- end
132
+ context "when through is specified" do
133
+ it "should raise an error if specified for an invalid query" do
134
+ expect{ subject.metric :test_metric, metric_proc, through: :fake }.to raise_error ArgumentError, 'query fake is not defined'
135
+ end
135
136
 
136
- it "should raise an error if specified for an invalid query" do
137
- expect{ subject.metric :test_metric, metric_proc, through: :fake }.to raise_error ArgumentError, 'query fake is not defined'
138
- end
137
+ it "should allow metrics to be defined with a block" do
138
+ subject.metric :block_metric, through: :test do
139
+ 123
140
+ end
139
141
 
140
- it "should allow metrics to be defined with a block" do
141
- subject.metric :block_metric, through: :test do
142
- 123
142
+ subject.queries[:test].metrics[:block_metric].run(self, nil).should == 123
143
143
  end
144
144
 
145
- subject.queries[:test].metrics[:block_metric].run(self, nil).should == 123
145
+ it "should allow metrics to be defined with a lambda" do
146
+ subject.metric :block_metric, -> * { 123 }, through: :test
147
+ subject.queries[:test].metrics[:block_metric].run(self, nil).should == 123
148
+ end
146
149
  end
147
150
 
148
- it "should allow metrics to be defined with a lambda" do
149
- subject.metric :block_metric, -> * { 123 }, through: :test
150
- subject.queries[:test].metrics[:block_metric].run(self, nil).should == 123
151
+ context "when through is not specified" do
152
+ before { subject.metric(:no_through_metric) { |data| data } }
153
+
154
+ its(:queries) { should include :__metric_no_through_metric }
155
+
156
+ it "should return the result of the query as the result of the metric" do
157
+ subject.queries[:__metric_no_through_metric].metrics[:no_through_metric].run(self, [123]).should == 123
158
+ end
151
159
  end
152
160
  end
153
161
 
data/spec/report_spec.rb CHANGED
@@ -39,7 +39,9 @@ describe Compendium::Report do
39
39
  [params[:first].__getobj__, params[:second].__getobj__]
40
40
  end
41
41
 
42
- metric :test_metric, -> results { results.to_a.max }, through: :test
42
+ metric :lambda_metric, -> results { results.to_a.max }, through: :test
43
+ metric(:block_metric, through: :test) { |results| results.to_a.max }
44
+ metric(:implicit_metric) { [1, 2, 3].count }
43
45
  end
44
46
  end
45
47
 
@@ -53,14 +55,25 @@ describe Compendium::Report do
53
55
 
54
56
  its('test_results.records') { should == [Date.new(2010, 10, 10), Date.new(2011, 11, 11)] }
55
57
 
56
- it "should run its metrics" do
57
- subject.test.metrics[:test_metric].result.should == Date.new(2011, 11, 11)
58
- subject.metrics[:test_metric].result.should == Date.new(2011, 11, 11)
58
+ it "should allow metric results to be accessed through a query" do
59
+ subject.test.metrics[:lambda_metric].result.should == Date.new(2011, 11, 11)
60
+ end
61
+
62
+ it "should run its metrics defined as a lambda" do
63
+ subject.metrics[:lambda_metric].result.should == Date.new(2011, 11, 11)
64
+ end
65
+
66
+ it "should run its metrics defined as a block" do
67
+ subject.metrics[:block_metric].result.should == Date.new(2011, 11, 11)
68
+ end
69
+
70
+ it "should run its implicit metrics" do
71
+ subject.metrics[:implicit_metric].result.should == 3
59
72
  end
60
73
 
61
74
  it "should not affect other instances of the report class" do
62
75
  report2.test.results.should be_nil
63
- report2.metrics[:test_metric].result.should be_nil
76
+ report2.metrics[:lambda_metric].result.should be_nil
64
77
  end
65
78
 
66
79
  it "should not affect the class collections" do
@@ -122,11 +135,46 @@ describe Compendium::Report do
122
135
  subject.second.should_not have_run
123
136
  end
124
137
 
138
+ it "should allow multiple queries to be specified by :only" do
139
+ report_class.query(:third) {}
140
+ subject.run(nil, only: [:first, :third])
141
+ subject.first.should have_run
142
+ subject.second.should_not have_run
143
+ subject.third.should have_run
144
+ end
145
+
146
+ it "should not run through queries related to a query specified by only if not also specified" do
147
+ report_class.query(:through, through: :first) {}
148
+ subject.run(nil, only: :first)
149
+ subject.through.should_not have_run
150
+ end
151
+
152
+ it "should run through queries related to a query specified by only if also specified" do
153
+ report_class.query(:through, through: :first) {}
154
+ subject.run(nil, only: [:first, :through])
155
+ subject.through.should have_run
156
+ end
157
+
125
158
  it "should not run queries specified by :except" do
126
159
  subject.run(nil, except: :first)
127
160
  subject.first.should_not have_run
128
161
  subject.second.should have_run
129
162
  end
163
+
164
+ it "should allow multiple queries to be specified by :except" do
165
+ report_class.query(:third) {}
166
+ subject.run(nil, except: [:first, :third])
167
+ subject.first.should_not have_run
168
+ subject.second.should have_run
169
+ subject.third.should_not have_run
170
+ end
171
+
172
+ it "should not run through queries excepted related to a query even if the main query is not excepted" do
173
+ report_class.query(:through, through: :first) {}
174
+ subject.run(nil, except: :through)
175
+ subject.through.should_not have_run
176
+ subject.first.should have_run
177
+ end
130
178
  end
131
179
  end
132
180
 
@@ -19,5 +19,10 @@ describe Compendium::ResultSet do
19
19
  let(:results) { { one: 1, two: 2 } }
20
20
  it { should == { one: 1, two: 2 } }
21
21
  end
22
+
23
+ context "when given a scalar" do
24
+ let(:results) { 3 }
25
+ it { should == [3] }
26
+ end
22
27
  end
23
28
  end
@@ -35,6 +35,30 @@ describe Compendium::ThroughQuery do
35
35
 
36
36
  before { parent3.stub(:execute_query) { |cmd| cmd } }
37
37
 
38
+ it "should pass along the params if the proc collects it" do
39
+ params = { one: 1, two: 2 }
40
+ q = described_class.new(:through, parent3, {}, -> r, params { params })
41
+ q.run(params).should == params
42
+ end
43
+
44
+ it "should pass along the params if the proc has a splat argument" do
45
+ params = { one: 1, two: 2 }
46
+ q = described_class.new(:through, parent3, {}, -> *args { args })
47
+ q.run(params).should == [[[1, 2, 3]], params.with_indifferent_access]
48
+ end
49
+
50
+ it "should not pass along the params if the proc doesn't collects it" do
51
+ params = { one: 1, two: 2 }
52
+ q = described_class.new(:through, parent3, {}, -> r { r })
53
+ q.run(params).should == [[1, 2, 3]]
54
+ end
55
+
56
+ it "should not affect its parent query" do
57
+ q = described_class.new(:through, parent3, {}, -> r { r.map!{ |i| i * 2 } })
58
+ q.run(nil).should == [[1, 2, 3, 1, 2, 3]]
59
+ parent3.results.should == [[1, 2, 3]]
60
+ end
61
+
38
62
  context "with a single parent" do
39
63
  subject { described_class.new(:sub, parent1, {}, -> r { r.first }) }
40
64
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compendium
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Vandersluis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2013-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  type: :runtime