compendium 1.0.1 → 1.0.2
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 +8 -8
- data/app/assets/stylesheets/compendium/_metrics.css.scss +1 -1
- data/compendium.gemspec +1 -1
- data/config/initializers/ruby/hash.rb +6 -0
- data/lib/compendium/dsl.rb +1 -0
- data/lib/compendium/option.rb +1 -1
- data/lib/compendium/query.rb +29 -8
- data/lib/compendium/report.rb +16 -2
- data/lib/compendium/version.rb +1 -1
- data/spec/dsl_spec.rb +6 -0
- data/spec/query_spec.rb +64 -0
- data/spec/report_spec.rb +76 -37
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Y2M5ZWFmZjNlN2Q0YWQ0MGQ4ZTQ0Njg3ZDIzN2VjMTI4NzZlOTJlYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjFkNjcwNmU2YTRlOTNhZTdiZjYyYmU0MzA1MDEzZGJhMjdmOGQ3MQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NjlmNzliZjA5MjU3N2E4Mzk2NzZkOWM0M2JmM2YzYzk1YWNjNDQ1MjgyZTc3
|
10
|
+
MGFkNzM5ODc4YzI1NGUyMzM1ZDliMWE1ZDY5NmQ2YTQzMjFkNjgzOGNiMzQy
|
11
|
+
ZGM3NWI5OTA5YjlhMGY0YzMwMjYwNzYzNjJiYjQ5ODE1MDY0NTM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODAwYmEwOTJhMmViNTczMTQ4ZGNmYTY0ZGZmZjNjZTZkYjJjMTAwNzNiYjgx
|
14
|
+
ZmEyOTA0MDRjNmFkMWNiMWM5NzQ3ZTYyYzkzMDlmYzY4ZTk0YTczOTgyZTgy
|
15
|
+
MTc3ODZmYjU4NGY1MDA4NGJmMjVmNDgyNjIzOTE5YzcyY2Y4NzA=
|
data/compendium.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency 'rails', '>= 3.0.0'
|
22
22
|
gem.add_dependency 'sass-rails', '>= 3.0.0'
|
23
23
|
gem.add_dependency 'compass-rails', '>= 1.0.0'
|
24
|
-
gem.add_dependency 'collection_of', '
|
24
|
+
gem.add_dependency 'collection_of', '1.0.4'
|
25
25
|
gem.add_dependency 'inheritable_attr', '>= 1.0.0'
|
26
26
|
gem.add_development_dependency 'rspec', '~> 2.0'
|
27
27
|
end
|
data/lib/compendium/dsl.rb
CHANGED
@@ -22,6 +22,7 @@ module Compendium
|
|
22
22
|
|
23
23
|
if options[name]
|
24
24
|
options[name].type = type if type
|
25
|
+
options[name].default = opts.delete(:default) if opts.key?(:default)
|
25
26
|
options[name].merge!(opts)
|
26
27
|
else
|
27
28
|
options[name] = Compendium::Option.new(opts.merge(name: name, type: type))
|
data/lib/compendium/option.rb
CHANGED
@@ -5,7 +5,7 @@ require 'active_support/core_ext/module/delegation'
|
|
5
5
|
|
6
6
|
module Compendium
|
7
7
|
class Option
|
8
|
-
|
8
|
+
attr_accessor :name, :type, :default, :choices, :options
|
9
9
|
|
10
10
|
delegate :boolean?, :date?, :dropdown?, :radio?, :text?, to: :type
|
11
11
|
delegate :merge, :merge!, :[], to: :@options
|
data/lib/compendium/query.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
require 'compendium/result_set'
|
2
2
|
require 'compendium/params'
|
3
3
|
require 'collection_of'
|
4
|
+
require_relative '../../config/initializers/ruby/hash'
|
4
5
|
|
5
6
|
module Compendium
|
6
7
|
class Query
|
7
8
|
attr_reader :name, :results, :metrics
|
8
9
|
attr_accessor :options, :proc, :through, :report
|
9
10
|
|
10
|
-
def initialize(
|
11
|
-
@
|
12
|
-
|
13
|
-
@
|
11
|
+
def initialize(*args)
|
12
|
+
@report = args.shift if arg_is_report?(args.first)
|
13
|
+
|
14
|
+
raise ArgumentError, "wrong number of arguments (#{args.size + (@report ? 1 : 0)} for 3..4)" unless args.size == 3
|
15
|
+
|
16
|
+
@name, @options, @proc = args
|
14
17
|
@metrics = ::Collection[Metric]
|
15
18
|
end
|
16
19
|
|
@@ -50,10 +53,14 @@ module Compendium
|
|
50
53
|
private
|
51
54
|
|
52
55
|
def collect_results(params, context)
|
53
|
-
|
54
|
-
params
|
56
|
+
if through.nil?
|
57
|
+
args = params
|
55
58
|
else
|
56
|
-
collect_through_query_results(through, params, context)
|
59
|
+
args = collect_through_query_results(through, params, context)
|
60
|
+
|
61
|
+
# If none of the through queries have any results, we shouldn't try to execute the query, because it
|
62
|
+
# depends on the results of its parents.
|
63
|
+
return @results = ResultSet.new([]) if args.compact.empty?
|
57
64
|
end
|
58
65
|
|
59
66
|
command = context.instance_exec(args, &proc) if proc
|
@@ -69,10 +76,20 @@ module Compendium
|
|
69
76
|
if options.key?(:through) or options.fetch(:collect, nil) == :active_record
|
70
77
|
command
|
71
78
|
else
|
72
|
-
|
79
|
+
execute_command(command)
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
83
|
+
def execute_command(command)
|
84
|
+
return [] if command.nil?
|
85
|
+
command = command.to_sql if command.respond_to?(:to_sql)
|
86
|
+
execute_query(command)
|
87
|
+
end
|
88
|
+
|
89
|
+
def execute_query(command)
|
90
|
+
::ActiveRecord::Base.connection.select_all(command)
|
91
|
+
end
|
92
|
+
|
76
93
|
def collect_through_query_results(through, params, context)
|
77
94
|
results = {}
|
78
95
|
|
@@ -90,5 +107,9 @@ module Compendium
|
|
90
107
|
def get_through_query(name)
|
91
108
|
report.queries[name]
|
92
109
|
end
|
110
|
+
|
111
|
+
def arg_is_report?(arg)
|
112
|
+
arg.is_a?(Report) or (arg.is_a?(Class) and arg < Report)
|
113
|
+
end
|
93
114
|
end
|
94
115
|
end
|
data/lib/compendium/report.rb
CHANGED
@@ -19,11 +19,25 @@ module Compendium
|
|
19
19
|
queries.each { |q| q.report = self }
|
20
20
|
end
|
21
21
|
|
22
|
-
def run(context = nil)
|
22
|
+
def run(context = nil, options = {})
|
23
23
|
self.context = context
|
24
24
|
self.results = {}
|
25
25
|
|
26
|
-
|
26
|
+
only = options.delete(:only)
|
27
|
+
except = options.delete(:except)
|
28
|
+
|
29
|
+
raise ArgumentError, 'cannot specify only and except options at the same time' if only && except
|
30
|
+
([only] + [except]).flatten.compact.each { |q| raise ArgumentError, 'invalid query #{q}' unless queries.include?(q) }
|
31
|
+
|
32
|
+
queries_to_run = if only
|
33
|
+
queries.slice(only)
|
34
|
+
elsif except
|
35
|
+
queries.except(except)
|
36
|
+
else
|
37
|
+
queries
|
38
|
+
end
|
39
|
+
|
40
|
+
queries_to_run.each{ |q| self.results[q.name] = q.run(params, ContextWrapper.wrap(context, self)) }
|
27
41
|
|
28
42
|
self
|
29
43
|
end
|
data/lib/compendium/version.rb
CHANGED
data/spec/dsl_spec.rb
CHANGED
@@ -19,6 +19,12 @@ describe Compendium::DSL do
|
|
19
19
|
subject.options[:starting_on].should be_boolean
|
20
20
|
subject.options[:starting_on].should_not be_date
|
21
21
|
end
|
22
|
+
|
23
|
+
it "should allow overriding default value" do
|
24
|
+
proc = -> { Date.new(2013, 6, 1) }
|
25
|
+
subject.option :starting_on, :date, default: proc
|
26
|
+
subject.options[:starting_on].default.should == proc
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
24
30
|
describe "#query" do
|
data/spec/query_spec.rb
CHANGED
@@ -1,6 +1,30 @@
|
|
1
1
|
require 'compendium/query'
|
2
2
|
|
3
3
|
describe Compendium::Query do
|
4
|
+
describe "#initialize" do
|
5
|
+
let(:options) { double("Options") }
|
6
|
+
let(:proc) { double("Proc") }
|
7
|
+
|
8
|
+
context "when supplying a report" do
|
9
|
+
let(:r) { Compendium::Report.new }
|
10
|
+
subject { described_class.new(r, :test, options, proc)}
|
11
|
+
|
12
|
+
its(:report) { should == r }
|
13
|
+
its(:name) { should == :test }
|
14
|
+
its(:options) { should == options }
|
15
|
+
its(:proc) { should == proc }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when not supplying a report" do
|
19
|
+
subject { described_class.new(:test, options, proc)}
|
20
|
+
|
21
|
+
its(:report) { should be_nil }
|
22
|
+
its(:name) { should == :test }
|
23
|
+
its(:options) { should == options }
|
24
|
+
its(:proc) { should == proc }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
4
28
|
describe "#run" do
|
5
29
|
let(:query) { described_class.new(:test, {}, -> * { [1, 2, 3] }) }
|
6
30
|
before { query.stub(:fetch_results) { |c| c } }
|
@@ -19,6 +43,46 @@ describe Compendium::Query do
|
|
19
43
|
query.run(nil)
|
20
44
|
q2.should_not have_run
|
21
45
|
end
|
46
|
+
|
47
|
+
it "should return an empty result set if running an query with no proc" do
|
48
|
+
query = described_class.new(:blank, {}, nil)
|
49
|
+
query.run(nil).should be_empty
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'through queries' do
|
53
|
+
let(:parent_query1) { described_class.new(:parent1, {}, -> * { }) }
|
54
|
+
let(:parent_query2) { described_class.new(:parent2, {}, -> * { }) }
|
55
|
+
let(:parent_query3) { described_class.new(:parent3, {}, -> * { [[1, 2, 3]] }) }
|
56
|
+
|
57
|
+
subject { described_class.new(:sub, {}, -> records { records.first }) }
|
58
|
+
|
59
|
+
before do
|
60
|
+
subject.stub(:get_through_query).with(:parent1).and_return(parent_query1)
|
61
|
+
subject.stub(:get_through_query).with(:parent2).and_return(parent_query2)
|
62
|
+
subject.stub(:get_through_query).with(:parent3).and_return(parent_query3)
|
63
|
+
described_class.any_instance.stub(:execute_query) { |cmd| cmd }
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not try to run a through query if the parent query has no results" do
|
67
|
+
subject.through = :parent1
|
68
|
+
|
69
|
+
expect { subject.run(nil) }.to_not raise_error
|
70
|
+
subject.results.should be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not try to run a through query with multiple parents all of which have no results" do
|
74
|
+
subject.through = [:parent1, :parent2]
|
75
|
+
|
76
|
+
expect { subject.run(nil) }.to_not raise_error
|
77
|
+
subject.results.should be_empty
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should allow non blank queries" do
|
81
|
+
subject.through = :parent3
|
82
|
+
subject.run(nil)
|
83
|
+
subject.results.should == [1, 2, 3]
|
84
|
+
end
|
85
|
+
end
|
22
86
|
end
|
23
87
|
|
24
88
|
describe "#nil?" do
|
data/spec/report_spec.rb
CHANGED
@@ -29,64 +29,103 @@ describe Compendium::Report do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#run" do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
context do
|
33
|
+
let(:report_class) do
|
34
|
+
Class.new(Compendium::Report) do
|
35
|
+
option :first, :date
|
36
|
+
option :second, :date
|
36
37
|
|
37
|
-
|
38
|
-
|
38
|
+
query :test do |params|
|
39
|
+
[params[:first].__getobj__, params[:second].__getobj__]
|
40
|
+
end
|
41
|
+
|
42
|
+
metric :test_metric, -> results { results.to_a.max }, through: :test
|
39
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
subject { report_class.new(first: '2010-10-10', second: '2011-11-11') }
|
47
|
+
let!(:report2) { report_class.new }
|
40
48
|
|
41
|
-
|
49
|
+
before do
|
50
|
+
Compendium::Query.any_instance.stub(:fetch_results) { |c| c }
|
51
|
+
subject.run
|
42
52
|
end
|
43
|
-
end
|
44
53
|
|
45
|
-
|
46
|
-
let!(:report2) { report_class.new }
|
54
|
+
its('test_results.records') { should == [Date.new(2010, 10, 10), Date.new(2011, 11, 11)] }
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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)
|
59
|
+
end
|
52
60
|
|
53
|
-
|
61
|
+
it "should not affect other instances of the report class" do
|
62
|
+
report2.test.results.should be_nil
|
63
|
+
report2.metrics[:test_metric].result.should be_nil
|
64
|
+
end
|
54
65
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
66
|
+
it "should not affect the class collections" do
|
67
|
+
report_class.test.results.should be_nil
|
68
|
+
end
|
59
69
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
70
|
+
context "with through queries" do
|
71
|
+
let(:report_class) do
|
72
|
+
Class.new(Compendium::Report) do
|
73
|
+
option :first, :boolean, default: false
|
74
|
+
query(:test) { |params| !!params[:first] ? [100, 200, 400, 800] : [1600, 3200, 6400]}
|
75
|
+
query(:through, through: :test) { |results| [results.first] }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
subject { report_class.new(first: true) }
|
80
|
+
|
81
|
+
its('through.results') { should == [100] }
|
64
82
|
|
65
|
-
|
66
|
-
|
83
|
+
it "should not mark other instances' queries as ran" do
|
84
|
+
report2.test.should_not have_run
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not affect other instances" do
|
88
|
+
report2.queries.each { |q| q.stub(:fetch_results) { |c| c } }
|
89
|
+
report2.run
|
90
|
+
report2.through.results.should == [1600]
|
91
|
+
end
|
92
|
+
end
|
67
93
|
end
|
68
94
|
|
69
|
-
context "
|
95
|
+
context "when specifying which queries to run" do
|
70
96
|
let(:report_class) do
|
71
97
|
Class.new(Compendium::Report) do
|
72
|
-
|
73
|
-
query
|
74
|
-
query(:through, through: :test) { |results| [results.first] }
|
98
|
+
query :first
|
99
|
+
query :second
|
75
100
|
end
|
76
101
|
end
|
77
102
|
|
78
|
-
subject { report_class.new
|
103
|
+
subject { report_class.new }
|
104
|
+
|
105
|
+
it "should raise an error if given :only and :except options" do
|
106
|
+
expect{ subject.run(nil, only: :first, except: :second) }.to raise_error(ArgumentError)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should raise an error if given an invalid query name" do
|
110
|
+
expect{ subject.run(nil, only: :foo) }.to raise_error(ArgumentError)
|
111
|
+
end
|
79
112
|
|
80
|
-
|
113
|
+
it "should run all queries if nothing is specified" do
|
114
|
+
subject.run(nil)
|
115
|
+
subject.first.should have_run
|
116
|
+
subject.second.should have_run
|
117
|
+
end
|
81
118
|
|
82
|
-
it "should
|
83
|
-
|
119
|
+
it "should only run queries specified by :only" do
|
120
|
+
subject.run(nil, only: :first)
|
121
|
+
subject.first.should have_run
|
122
|
+
subject.second.should_not have_run
|
84
123
|
end
|
85
124
|
|
86
|
-
it "should not
|
87
|
-
|
88
|
-
|
89
|
-
|
125
|
+
it "should not run queries specified by :except" do
|
126
|
+
subject.run(nil, except: :first)
|
127
|
+
subject.first.should_not have_run
|
128
|
+
subject.second.should have_run
|
90
129
|
end
|
91
130
|
end
|
92
131
|
end
|
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
|
+
version: 1.0.2
|
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
|
+
date: 2013-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
type: :runtime
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
name: collection_of
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- -
|
61
|
+
- - '='
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 1.0.
|
63
|
+
version: 1.0.4
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.
|
68
|
+
version: 1.0.4
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- app/views/compendium/reports/setup.haml
|
124
124
|
- compendium.gemspec
|
125
125
|
- config/initializers/rails/active_record/connection_adapters/quoting.rb
|
126
|
+
- config/initializers/ruby/hash.rb
|
126
127
|
- config/initializers/ruby/numeric.rb
|
127
128
|
- config/locales/en.yml
|
128
129
|
- lib/compendium.rb
|