compendium 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|