compendium 1.0.7 → 1.1.0
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/CHANGELOG.md +18 -0
- data/README.md +10 -0
- data/app/classes/compendium/presenters/chart.rb +43 -8
- data/lib/compendium/abstract_chart_provider.rb +10 -11
- data/lib/compendium/dsl.rb +8 -0
- data/lib/compendium/query.rb +42 -8
- data/lib/compendium/report.rb +20 -0
- data/lib/compendium/version.rb +1 -1
- data/spec/dsl_spec.rb +31 -2
- data/spec/presenters/chart_spec.rb +38 -4
- data/spec/query_spec.rb +51 -2
- data/spec/report_spec.rb +5 -0
- metadata +3 -3
- data/lib/compendium/chart_provider/amcharts.rb +0 -20
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzRhZmU5NjE5ZTIzMGZmM2JmMzhlNDRhNjY3NTQ2ZjRjYzI0ZDkxNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODk2NGYxNjU1YzgzZTlkZmM5MmU1ZjljZjNlNjdkZGE1YTY0ZmY1Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OThmYTFhNmQ2MWY0NTdmYmQxYzg2OTkzYzViNThmMTNjNzhhNDgzMjU4NmQ2
|
10
|
+
NjYyMThlMzQyMDY4NzU1YWY0MTdiNGIyYWFjNzdlMzgzMGMyZjY0MTk0MjU2
|
11
|
+
MzEyYTVjMGE1ZTQ2NTczN2YyOWM5ZTg1YTk1Mzg3ZjYxOTNjOGI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2M1NzdhOGQzMWVhZjNmNGVlZTVlY2JiOWQzZTFlZTkzZGY4ZjE5YjdiMWVi
|
14
|
+
ZGU2MzY3ZTU4ZTFiNzU4MDQxNTA5ZjBlZTlmY2YyNGIyM2ZlZWQ3MzNhYzMz
|
15
|
+
ZjExMWFhOWZhZTIwOGQwZjJlOGQ2ZGE1OTFhYjAxOTA2MzEwMGE=
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## 1.1.0 (unreleased)
|
4
|
+
* Added query filters (allow a result set to be filtered to remove/translate/etc. data)
|
5
|
+
* Extract chart providers into their own gems
|
6
|
+
* Allow queries to be rendered as charts without having been run yet (to set up for a future AJAX load)
|
7
|
+
* Added `Report#url` and `Query#url` methods to get the JSON URL
|
8
|
+
|
9
|
+
## 1.0.7
|
10
|
+
* Added the ability to render a report or a specific query of a report as JSON
|
11
|
+
|
12
|
+
## 1.0.6
|
13
|
+
* Added a built-in renderer for metrics
|
14
|
+
|
15
|
+
## 1.0.5
|
16
|
+
* Fixed the `:only` and `:except` options to `Report#run`
|
17
|
+
* Give `ThroughQuery` access to params if the definition block has an arity of 2
|
18
|
+
* Fixed mutating results in a `ThroughQuery` block affecting the parent query
|
data/README.md
CHANGED
@@ -24,6 +24,16 @@ class MyReport < Compendium::Report
|
|
24
24
|
Items.where(delivered: true, purchased_at: (params[:starting_on]..params[:ending_on]))
|
25
25
|
end
|
26
26
|
|
27
|
+
# Define a filter to modify the results from specified query (in this case :deliveries)
|
28
|
+
# For example, this can be useful to translate columns prior to rendering, as it will apply
|
29
|
+
# for all render types (table, chart, JSON)
|
30
|
+
# Note: A filter can be applied to multiple queries at once
|
31
|
+
filter :deliveries do |results, params|
|
32
|
+
results.each do |row|
|
33
|
+
row['price'] = sprintf('$%.2f', row['price'])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
# Define a query which collects data by using AR directly
|
28
38
|
query :on_hand_inventory, collect: :active_record do |params|
|
29
39
|
Items.where(in_stock: true)
|
@@ -3,17 +3,25 @@ require 'active_support/core_ext/array/extract_options'
|
|
3
3
|
|
4
4
|
module Compendium::Presenters
|
5
5
|
class Chart < Query
|
6
|
-
attr_reader :data, :container, :chart_provider
|
6
|
+
attr_reader :data, :params, :container, :chart_provider
|
7
|
+
attr_accessor :options
|
7
8
|
|
8
9
|
def initialize(template, object, *args, &setup)
|
9
|
-
options = args.extract_options!
|
10
|
-
type, container = args
|
11
|
-
|
12
10
|
super(template, object)
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
self.options = args.extract_options!
|
13
|
+
type, container = args
|
14
|
+
|
15
|
+
if remote?
|
16
|
+
# If the query hasn't run yet, render a chart that loads its data remotely (ie. through AJAX)
|
17
|
+
# ie. if rendering a query from a report class directly
|
18
|
+
@data = query.url
|
19
|
+
@params = collect_params
|
20
|
+
else
|
21
|
+
@data = options[:index] ? results.records[options[:index]] : results
|
22
|
+
@data = @data.records if @data.is_a?(Compendium::ResultSet)
|
23
|
+
@data = @data[0...-1] if query.options[:totals]
|
24
|
+
end
|
17
25
|
|
18
26
|
@container = container || query.name
|
19
27
|
|
@@ -32,7 +40,34 @@ module Compendium::Presenters
|
|
32
40
|
end
|
33
41
|
|
34
42
|
def initialize_chart_provider(type, &setup)
|
35
|
-
@chart_provider = provider.new(type, @data, &setup)
|
43
|
+
@chart_provider = provider.new(type, @data, @params, &setup)
|
44
|
+
end
|
45
|
+
|
46
|
+
def collect_params
|
47
|
+
params = {}
|
48
|
+
params[:report] = options[:params] if options[:params]
|
49
|
+
|
50
|
+
if remote? and protected_against_csrf?
|
51
|
+
# If we're loading remotely, and CSRF protection is enabled,
|
52
|
+
# automatically include the CSRF token in AJAX params
|
53
|
+
params.merge!(form_authenticity_param)
|
54
|
+
end
|
55
|
+
|
56
|
+
params
|
57
|
+
end
|
58
|
+
|
59
|
+
# You can force the chart to render remote data, even if the query has already run by passing the remote: true option
|
60
|
+
def remote?
|
61
|
+
!query.ran? || options.fetch(:remote, false)
|
62
|
+
end
|
63
|
+
|
64
|
+
def protected_against_csrf?
|
65
|
+
!@template.controller.forgery_protection_strategy.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def form_authenticity_param
|
69
|
+
return {} unless protected_against_csrf?
|
70
|
+
{ @template.controller.request_forgery_protection_token => @template.controller.send(:form_authenticity_token) }
|
36
71
|
end
|
37
72
|
end
|
38
73
|
end
|
@@ -3,10 +3,17 @@ require 'active_support/core_ext/string/inflections'
|
|
3
3
|
module Compendium
|
4
4
|
# Abstract wrapper for rendering charts
|
5
5
|
# To add a new chart provider, #initialize and #render must be implemented
|
6
|
+
# Custom providers should also override Compendium::AbstractChartProvider.find_chart_provider (but fallback to super)
|
7
|
+
|
6
8
|
class AbstractChartProvider
|
7
9
|
attr_reader :chart
|
8
10
|
|
9
|
-
|
11
|
+
# @param type [Symbol] The type of chart you want to render (:pie, :line, etc).
|
12
|
+
# Accepted types might vary by provider.
|
13
|
+
# @param data_or_url [Enumerable or String] The data or URL to the data you wish to render.
|
14
|
+
# Providers may not support loading data remotely.
|
15
|
+
# @param params [Hash] If data_or_url is a URL, the params to use for the AJAX request
|
16
|
+
def initialize(type, data_or_url, params = {}, &setup_proc)
|
10
17
|
raise NotImplementedError
|
11
18
|
end
|
12
19
|
|
@@ -14,17 +21,9 @@ module Compendium
|
|
14
21
|
raise NotImplementedError
|
15
22
|
end
|
16
23
|
|
17
|
-
#
|
24
|
+
# Chart providers need to override this method to add a hook for themselves
|
18
25
|
def self.find_chart_provider
|
19
|
-
|
20
|
-
:AmCharts
|
21
|
-
else
|
22
|
-
self.name.demodulize.to_sym
|
23
|
-
end
|
26
|
+
nil
|
24
27
|
end
|
25
28
|
end
|
26
|
-
|
27
|
-
module ChartProvider
|
28
|
-
autoload :AmCharts, 'compendium/chart_provider/amcharts'
|
29
|
-
end
|
30
29
|
end
|
data/lib/compendium/dsl.rb
CHANGED
@@ -49,6 +49,13 @@ module Compendium
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def filter(*query_names, &block)
|
53
|
+
query_names.each do |query_name|
|
54
|
+
raise ArgumentError, "query #{query_name} is not defined" unless queries.key?(query_name)
|
55
|
+
queries[query_name].add_filter(block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
52
59
|
# Each Report will have its own descendant of Params in order to safely add validations
|
53
60
|
def params_class
|
54
61
|
@params_class ||= Class.new(Params)
|
@@ -95,6 +102,7 @@ module Compendium
|
|
95
102
|
end
|
96
103
|
|
97
104
|
query = query_type.new(*params)
|
105
|
+
query.report = self
|
98
106
|
|
99
107
|
metrics[name] = opts[:metric] if opts.key?(:metric)
|
100
108
|
queries << query
|
data/lib/compendium/query.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative '../../config/initializers/ruby/hash'
|
|
7
7
|
|
8
8
|
module Compendium
|
9
9
|
class Query
|
10
|
-
attr_reader :name, :results, :metrics
|
10
|
+
attr_reader :name, :results, :metrics, :filters
|
11
11
|
attr_accessor :options, :proc, :report
|
12
12
|
|
13
13
|
def initialize(*args)
|
@@ -17,6 +17,7 @@ module Compendium
|
|
17
17
|
|
18
18
|
@name, @options, @proc = args
|
19
19
|
@metrics = ::Collection[Metric]
|
20
|
+
@filters = ::Collection[Proc]
|
20
21
|
end
|
21
22
|
|
22
23
|
def initialize_clone(*)
|
@@ -25,22 +26,40 @@ module Compendium
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def run(params, context = self)
|
28
|
-
|
29
|
-
|
29
|
+
if report.is_a?(Class)
|
30
|
+
# If running a query directly from a class rather than an instance, the class's query should
|
31
|
+
# not be affected/modified, so run the query without a reference back to the report.
|
32
|
+
# Otherwise, if the class is subsequently instantiated, the instance will already have results.
|
33
|
+
dup.tap{ |q| q.report = nil }.run(params, context)
|
34
|
+
else
|
35
|
+
collect_results(context, params)
|
36
|
+
collect_metrics(context)
|
30
37
|
|
31
|
-
|
38
|
+
@results
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get a URL for this query (format: :json set by default)
|
43
|
+
def url(params = {})
|
44
|
+
report.url(params.merge(query: self.name))
|
32
45
|
end
|
33
46
|
|
34
47
|
def add_metric(name, proc, options = {})
|
35
48
|
Compendium::Metric.new(name, self.name, proc, options).tap { |m| @metrics << m }
|
36
49
|
end
|
37
50
|
|
51
|
+
def add_filter(filter)
|
52
|
+
@filters << filter
|
53
|
+
end
|
54
|
+
|
38
55
|
def render_table(template, *options, &block)
|
39
56
|
Compendium::Presenters::Table.new(template, self, *options, &block).render unless empty?
|
40
57
|
end
|
41
58
|
|
42
59
|
def render_chart(template, *options, &block)
|
43
|
-
|
60
|
+
# A query can be rendered regardless of if it has data or not
|
61
|
+
# Rendering a chart with no result set builds a chart scaffold which can be updated through AJAX
|
62
|
+
Compendium::Presenters::Chart.new(template, self, *options, &block).render
|
44
63
|
end
|
45
64
|
|
46
65
|
def ran?
|
@@ -55,15 +74,16 @@ module Compendium
|
|
55
74
|
|
56
75
|
# A query is empty if it has no results
|
57
76
|
def empty?
|
58
|
-
results.
|
77
|
+
results.blank?
|
59
78
|
end
|
60
79
|
|
61
80
|
private
|
62
81
|
|
63
82
|
def collect_results(context, *params)
|
64
83
|
command = context.instance_exec(*params, &proc) if proc
|
65
|
-
|
66
|
-
|
84
|
+
results = fetch_results(command)
|
85
|
+
results = filter_results(results, *params) if filters.any?
|
86
|
+
@results = ResultSet.new(results) if results
|
67
87
|
end
|
68
88
|
|
69
89
|
def collect_metrics(context)
|
@@ -74,6 +94,20 @@ module Compendium
|
|
74
94
|
(options.fetch(:collect, nil) == :active_record) ? command : execute_command(command)
|
75
95
|
end
|
76
96
|
|
97
|
+
def filter_results(results, params)
|
98
|
+
return unless results
|
99
|
+
|
100
|
+
filters.each do |f|
|
101
|
+
if f.arity == 2
|
102
|
+
results = f.call(results, params)
|
103
|
+
else
|
104
|
+
results = f.call(results)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
results
|
109
|
+
end
|
110
|
+
|
77
111
|
def execute_command(command)
|
78
112
|
return [] if command.nil?
|
79
113
|
command = command.to_sql if command.respond_to?(:to_sql)
|
data/lib/compendium/report.rb
CHANGED
@@ -11,6 +11,7 @@ module Compendium
|
|
11
11
|
extend Compendium::DSL
|
12
12
|
|
13
13
|
delegate :valid?, :errors, to: :params
|
14
|
+
delegate :name, :url, to: :class
|
14
15
|
|
15
16
|
class << self
|
16
17
|
def inherited(report)
|
@@ -27,6 +28,15 @@ module Compendium
|
|
27
28
|
}
|
28
29
|
end
|
29
30
|
|
31
|
+
def name
|
32
|
+
super.underscore.gsub(/_report$/,'').to_sym
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get a URL for this report (format: :json set by default)
|
36
|
+
def url(params = {})
|
37
|
+
path_helper(params)
|
38
|
+
end
|
39
|
+
|
30
40
|
# Define predicate methods for getting the report type
|
31
41
|
# ie. r.spending? checks that r == SpendingReport
|
32
42
|
def method_missing(name, *args, &block)
|
@@ -45,6 +55,16 @@ module Compendium
|
|
45
55
|
return true if name.to_s.end_with?('?') and Compendium.reports.include?(report_class)
|
46
56
|
super
|
47
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def path_helper(params)
|
62
|
+
unless Rails.application.routes.url_helpers.method_defined? :compendium_reports_run_path
|
63
|
+
raise ActionController::RoutingError, "compendium_reports_run_path must be defined"
|
64
|
+
end
|
65
|
+
|
66
|
+
Rails.application.routes.url_helpers.compendium_reports_run_path(self.name, params.reverse_merge(format: :json))
|
67
|
+
end
|
48
68
|
end
|
49
69
|
|
50
70
|
def initialize(params = {})
|
data/lib/compendium/version.rb
CHANGED
data/spec/dsl_spec.rb
CHANGED
@@ -60,8 +60,8 @@ describe Compendium::DSL do
|
|
60
60
|
r.test.report.should == r
|
61
61
|
end
|
62
62
|
|
63
|
-
it "should
|
64
|
-
subject.test.report.should
|
63
|
+
it "should relate a query to the report class" do
|
64
|
+
subject.test.report.should == subject
|
65
65
|
end
|
66
66
|
|
67
67
|
context "when given a through option" do
|
@@ -159,6 +159,35 @@ describe Compendium::DSL do
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
+
describe "#filter" do
|
163
|
+
let(:filter_proc) { ->{ :filter } }
|
164
|
+
|
165
|
+
it "should add a filter to the given query" do
|
166
|
+
subject.query :test
|
167
|
+
subject.filter :test, &filter_proc
|
168
|
+
subject.queries[:test].filters.should include filter_proc
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should raise an error if there is no query of the given name" do
|
172
|
+
expect { subject.filter :test, &filter_proc }.to raise_error(ArgumentError, "query test is not defined")
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should allow multiple filters to be defined for the same query" do
|
176
|
+
subject.query :test
|
177
|
+
subject.filter :test, &filter_proc
|
178
|
+
subject.filter :test, &->{ :another_filter }
|
179
|
+
subject.queries[:test].filters.count.should == 2
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should allow a filter to be applied to multiple queries at once" do
|
183
|
+
subject.query :query1
|
184
|
+
subject.query :query2
|
185
|
+
subject.filter :query1, :query2, &filter_proc
|
186
|
+
subject.queries[:query1].filters.should include filter_proc
|
187
|
+
subject.queries[:query2].filters.should include filter_proc
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
162
191
|
it "should allow previously defined queries to be redefined by name" do
|
163
192
|
subject.query :test_query
|
164
193
|
subject.test_query foo: :bar
|
@@ -2,16 +2,16 @@ require 'spec_helper'
|
|
2
2
|
require 'compendium/presenters/chart'
|
3
3
|
|
4
4
|
describe Compendium::Presenters::Chart do
|
5
|
+
let(:template) { double('Template', forgery_protection_strategy: nil, request_forgery_protection_token: :authenticity_token, form_authenticity_token: "ABCDEFGHIJ").as_null_object }
|
6
|
+
let(:query) { double('Query', name: 'test_query', results: results, ran?: true, options: {}).as_null_object }
|
7
|
+
let(:results) { Compendium::ResultSet.new([]) }
|
8
|
+
|
5
9
|
before do
|
6
10
|
described_class.any_instance.stub(:provider) { double('ChartProvider') }
|
7
11
|
described_class.any_instance.stub(:initialize_chart_provider)
|
8
12
|
end
|
9
13
|
|
10
14
|
describe '#initialize' do
|
11
|
-
let(:template) { double('Template') }
|
12
|
-
let(:query) { double('Query', name: 'test_query', results: results, options: {}) }
|
13
|
-
let(:results) { Compendium::ResultSet.new([]) }
|
14
|
-
|
15
15
|
context 'when all params are given' do
|
16
16
|
subject{ described_class.new(template, query, :pie, :container) }
|
17
17
|
|
@@ -33,5 +33,39 @@ describe Compendium::Presenters::Chart do
|
|
33
33
|
its(:data) { should == results.records[:one] }
|
34
34
|
its(:container) { should == 'test_query' }
|
35
35
|
end
|
36
|
+
|
37
|
+
context "when the query has not been run" do
|
38
|
+
before { query.stub(ran?: false, url: '/path/to/query.json') }
|
39
|
+
|
40
|
+
subject{ described_class.new(template, query, :pie, params: { foo: 'bar' }) }
|
41
|
+
|
42
|
+
its(:data) { should == '/path/to/query.json' }
|
43
|
+
its(:params) { should == { report: { foo: 'bar' } } }
|
44
|
+
|
45
|
+
context "when CSRF protection is enabled" do
|
46
|
+
before { template.stub(forgery_protection_strategy: double('CSRF')) }
|
47
|
+
|
48
|
+
its(:params) { should include authenticity_token: "ABCDEFGHIJ" }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when CSRF protection is disabled" do
|
52
|
+
its(:params) { should_not include authenticity_token: "ABCDEFGHIJ" }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#remote?' do
|
58
|
+
it 'should be true if options[:remote] is set to true' do
|
59
|
+
described_class.new(template, query, :pie, remote: true).should be_remote
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should be true if the query has not been run yet' do
|
63
|
+
query.stub(run?: false)
|
64
|
+
described_class.new(template, query, :pie).should_be_remote
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should be false otherwise' do
|
68
|
+
described_class.new(template, query, :pie).should_not be_remote
|
69
|
+
end
|
36
70
|
end
|
37
71
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -49,6 +49,43 @@ describe Compendium::Query do
|
|
49
49
|
query = described_class.new(:blank, {}, nil)
|
50
50
|
query.run(nil).should be_empty
|
51
51
|
end
|
52
|
+
|
53
|
+
it "should filter the result set if a filter is provided" do
|
54
|
+
query.add_filter(-> data { data.reject(&:odd?) })
|
55
|
+
query.run(nil).should == [2]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should run multiple filters if given" do
|
59
|
+
query.add_filter(-> data { data.reject(&:odd?) })
|
60
|
+
query.add_filter(-> data { data.reject(&:even?) })
|
61
|
+
query.run(nil).should == []
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when the query belongs to a report class" do
|
65
|
+
let(:report) do
|
66
|
+
Class.new(Compendium::Report) do
|
67
|
+
query(:test) { [1, 2, 3] }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
subject { report.queries[:test] }
|
72
|
+
|
73
|
+
before { described_class.any_instance.stub(:fetch_results) { |c| c } }
|
74
|
+
|
75
|
+
it "should return its results" do
|
76
|
+
subject.run(nil).should == [1, 2, 3]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not affect the report" do
|
80
|
+
subject.run(nil)
|
81
|
+
report.queries[:test].results.should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should not affect future instances of the report" do
|
85
|
+
subject.run(nil)
|
86
|
+
report.new.queries[:test].results.should be_nil
|
87
|
+
end
|
88
|
+
end
|
52
89
|
end
|
53
90
|
|
54
91
|
describe "#nil?" do
|
@@ -65,9 +102,10 @@ describe Compendium::Query do
|
|
65
102
|
let(:template) { double("Template") }
|
66
103
|
subject { described_class.new(:test, {}, -> * {}) }
|
67
104
|
|
68
|
-
it "should
|
105
|
+
it "should initialize a new Chart presenter if the query has no results" do
|
69
106
|
subject.stub(empty?: true)
|
70
|
-
|
107
|
+
Compendium::Presenters::Chart.should_receive(:new).with(template, subject).and_return(double("Presenter").as_null_object)
|
108
|
+
subject.render_chart(template)
|
71
109
|
end
|
72
110
|
|
73
111
|
it "should initialize a new Chart presenter if the query has results" do
|
@@ -92,4 +130,15 @@ describe Compendium::Query do
|
|
92
130
|
subject.render_table(template)
|
93
131
|
end
|
94
132
|
end
|
133
|
+
|
134
|
+
describe "#url" do
|
135
|
+
let(:report) { double("Report") }
|
136
|
+
subject { described_class.new(:test, {}, ->{}) }
|
137
|
+
before { subject.report = report }
|
138
|
+
|
139
|
+
it "should build a URL using its report's URL" do
|
140
|
+
report.should_receive(:url).with(query: :test)
|
141
|
+
subject.url
|
142
|
+
end
|
143
|
+
end
|
95
144
|
end
|
data/spec/report_spec.rb
CHANGED
@@ -28,6 +28,11 @@ describe Compendium::Report do
|
|
28
28
|
its(:metrics) { should_not equal report2.metrics }
|
29
29
|
end
|
30
30
|
|
31
|
+
describe ".name" do
|
32
|
+
subject { TestReport = Class.new(described_class) }
|
33
|
+
its(:name) { should == :test }
|
34
|
+
end
|
35
|
+
|
31
36
|
describe "#run" do
|
32
37
|
context do
|
33
38
|
let(:report_class) do
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Vandersluis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
type: :runtime
|
@@ -102,6 +102,7 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- .gitignore
|
105
|
+
- CHANGELOG.md
|
105
106
|
- Gemfile
|
106
107
|
- LICENSE.txt
|
107
108
|
- README.md
|
@@ -129,7 +130,6 @@ files:
|
|
129
130
|
- config/locales/en.yml
|
130
131
|
- lib/compendium.rb
|
131
132
|
- lib/compendium/abstract_chart_provider.rb
|
132
|
-
- lib/compendium/chart_provider/amcharts.rb
|
133
133
|
- lib/compendium/collection_query.rb
|
134
134
|
- lib/compendium/context_wrapper.rb
|
135
135
|
- lib/compendium/dsl.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Compendium
|
2
|
-
module ChartProvider
|
3
|
-
# Uses the amcharts.rb gem to provide charting
|
4
|
-
class AmCharts < Compendium::AbstractChartProvider
|
5
|
-
def initialize(type, data, &setup_proc)
|
6
|
-
@chart = chart_class(type).new(data, &setup_proc)
|
7
|
-
end
|
8
|
-
|
9
|
-
def render(template, container)
|
10
|
-
template.amchart(chart, container)
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def chart_class(type)
|
16
|
-
::AmCharts::Chart.const_get(type.to_s.titlecase)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|