ruby_reportable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm use 1.9.3@gems
2
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby_reportable (0.0.2)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rr (1.0.4)
11
+ rspec (2.10.0)
12
+ rspec-core (~> 2.10.0)
13
+ rspec-expectations (~> 2.10.0)
14
+ rspec-mocks (~> 2.10.0)
15
+ rspec-core (2.10.0)
16
+ rspec-expectations (2.10.0)
17
+ diff-lcs (~> 1.1.3)
18
+ rspec-mocks (2.10.1)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ rr
25
+ rspec
26
+ ruby_reportable!
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 John "asceth" Long
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ Ruby Reportable - reporting in ruby
2
+ ===================================
3
+
4
+
5
+ ## DESCRIPTION
6
+
7
+ Ruby Reportable is a DSL for writing reports using pure ruby. It allows you to use
8
+ existing code (ie your Rails application) to grab data and the manipulate it.
9
+
10
+ If you have loaded it then Ruby Reportable can report on it.
11
+
12
+
13
+ ## Examples
14
+
15
+ See examples/ directory
16
+
17
+ ## Usage
18
+
19
+ Using Ruby Reportable is as easy as ```include RubyReportable``` in a new class. The include lets Ruby Reportable know this class is a new report and also brings in the DSL.
20
+
21
+ ### Source
22
+
23
+ Your source is the start of your data. All available configuration is shown below.
24
+
25
+ ```ruby
26
+ source do
27
+ #
28
+ # define how your outputs will see each element of the source data
29
+ #
30
+ as :element # this is the default
31
+
32
+ # Whatever you want your starting data to be
33
+ logic do
34
+ ObjectSpace.each_object.to_a.group_by(&:class).to_a
35
+ end
36
+ end
37
+ ```
38
+
39
+ ## INSTALLATION
40
+
41
+ Install as a gem or use as part of your Gemfile
42
+
43
+ $ [sudo] gem install ruby_reportable
44
+
45
+
46
+
47
+
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require "rspec"
5
+ require "rspec/core/rake_task"
6
+
7
+ Rspec::Core::RakeTask.new(:spec)
8
+
9
+ gemspec = eval(File.read(File.join(Dir.pwd, "ruby_reportable.gemspec")))
10
+
11
+ task :build => "#{gemspec.full_name}.gem"
12
+
13
+ task :test => :spec
14
+
15
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["ruby_reportable.gemspec"] do
16
+ system "gem build ruby_reportable.gemspec"
17
+ system "gem install ruby_reportable-#{RubyReportable::VERSION}.gem"
18
+ end
19
+
data/design ADDED
@@ -0,0 +1,34 @@
1
+ RubyReportable.define :test do
2
+ source do
3
+ as :client_application
4
+
5
+ logic do
6
+ ClientApplication.joins(:assigned_worker, :client)
7
+ end
8
+
9
+ filter(:unless => proc { meta[:current_user].roles.include?(:all) }) do
10
+ source.where('client_applications.assigned_worker_id' => meta[:current_user].id)
11
+ end
12
+ end
13
+
14
+ output('CLTC #') { client_application.client.cltc_number }
15
+ output('Program') { client_application.program.to_s }
16
+ output('Worker') { client_application.assigned_worker.to_s }
17
+ output('Level of Care') { client_application.latest_assessment.care_level.to_s }
18
+
19
+
20
+ filter('Program') do
21
+ require
22
+ key :program
23
+ on :data
24
+ input(:multiple) { Program.all.map(&:to_s) }
25
+
26
+ logic do
27
+ client_application.program.to_s == input
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+
34
+ RubyReportable.reports[:test].run(:meta => {:current_user => nil}, :input => {:program => 'Community Choices'})
@@ -0,0 +1,16 @@
1
+ class ObjectSpaceReport
2
+ include RubyReportable
3
+
4
+ name 'Object Space By Class'
5
+
6
+ source do
7
+ as :object
8
+
9
+ logic do
10
+ ObjectSpace.each_object.to_a.group_by(&:class).to_a
11
+ end
12
+ end
13
+
14
+ output('Class') { object.first.to_s }
15
+ output('Total') { object.last.size }
16
+ end
@@ -0,0 +1,19 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'ruby_reportable/base'
10
+ require_relative 'ruby_reportable/filter'
11
+ require_relative 'ruby_reportable/output'
12
+ require_relative 'ruby_reportable/sandbox'
13
+ require_relative 'ruby_reportable/source'
14
+
15
+
16
+ require_relative 'ruby_reportable/report'
17
+
18
+
19
+
@@ -0,0 +1,15 @@
1
+ module RubyReportable
2
+ @@reports = {}
3
+
4
+ def self.included(base)
5
+ base.send :extend, RubyReportable::Report
6
+ base.clear
7
+
8
+ @@reports[base.to_s] = base
9
+ end
10
+
11
+ def self.reports
12
+ @@reports
13
+ end
14
+ end
15
+
@@ -0,0 +1,47 @@
1
+ module RubyReportable
2
+ class Filter
3
+ def initialize(name)
4
+ @options = {}
5
+ @options[:key] = name.to_s.downcase.gsub(' ', '_').gsub(/[^a-zA-Z_]+/, '')
6
+ @options[:name] = name
7
+ @options[:require] = false
8
+ end
9
+
10
+ def [](key)
11
+ @options[key]
12
+ end
13
+
14
+ def []=(key, value)
15
+ @options[key] = value
16
+ end
17
+
18
+ def require
19
+ self[:require] = true
20
+ end
21
+
22
+ def priority(value)
23
+ self[:priority] = value
24
+ end
25
+
26
+ def key(key)
27
+ self[:key] = key
28
+ end
29
+
30
+ def use?(&block)
31
+ self[:use] = block
32
+ end
33
+
34
+ def input(type, &block)
35
+ self[:input] = type
36
+ self[:collection] = block
37
+ end
38
+
39
+ def valid?(&block)
40
+ self[:valid] = block
41
+ end
42
+
43
+ def logic(&block)
44
+ self[:logic] = block
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ module RubyReportable
2
+ class Output
3
+ attr_accessor :name, :logic
4
+
5
+ def initialize(name, options, block)
6
+ @name = name
7
+ @options = options
8
+ @logic = block
9
+ end
10
+
11
+ def [](key)
12
+ @options[key]
13
+ end
14
+
15
+ def []=(key, value)
16
+ @options[key] = value
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,202 @@
1
+ module RubyReportable
2
+ module Report
3
+ attr_accessor :data_source, :outputs, :filters
4
+
5
+ def clear
6
+ @outputs = []
7
+ @filters = {}
8
+ @data_source = nil
9
+ @report = self.to_s
10
+ @category = 'Reports'
11
+ @meta = {}
12
+ end
13
+
14
+ def meta(key, value = nil, &block)
15
+ if block_given?
16
+ @meta[key] = block
17
+ else
18
+ if value.nil?
19
+ @meta[key]
20
+ else
21
+ @meta[key] = value
22
+ end
23
+ end
24
+ end
25
+
26
+ def report(string = nil)
27
+ if string.nil?
28
+ @report
29
+ else
30
+ @report = string
31
+ end
32
+ end
33
+
34
+ def category(string = nil)
35
+ if string.nil?
36
+ @category
37
+ else
38
+ @category = string
39
+ end
40
+ end
41
+
42
+ def source(&block)
43
+ @data_source = RubyReportable::Source.new
44
+ @data_source.instance_eval(&block)
45
+ end
46
+
47
+ def filter(name, &block)
48
+ @filters[name] = RubyReportable::Filter.new(name)
49
+ @filters[name].instance_eval(&block)
50
+ end
51
+
52
+ def finalize(&block)
53
+ @finalize = block
54
+ end
55
+
56
+ def output(name, options = {}, &block)
57
+ @outputs << RubyReportable::Output.new(name, options, block)
58
+ end
59
+
60
+
61
+ #
62
+ # methods you shouldn't use inside the blocks
63
+ #
64
+ def useable_filters(scope)
65
+ @filters.values.select {|filter| !filter[:input].nil? && (filter[:use].nil? || filter[:use].call(scope))}.sort_by {|filter| filter[:priority].to_i}
66
+ end
67
+
68
+ def _filter(filters, original_sandbox, options)
69
+ # sort filters by priority then apply to sandbox
70
+ filters.sort_by do |filter_name, filter|
71
+ filter[:priority]
72
+ end.inject(original_sandbox) do |sandbox, (filter_name, filter)|
73
+
74
+ # find input for given filter
75
+ sandbox[:input] = options[:input][filter[:key]] if options[:input].is_a?(Hash)
76
+
77
+ if filter[:valid].nil? || sandbox.instance_eval(&filter[:valid])
78
+ if filter[:logic].nil?
79
+ sandbox
80
+ else
81
+ sandbox.build(:source, filter[:logic])
82
+ end
83
+ else
84
+ sandbox
85
+ end
86
+ end
87
+ end
88
+
89
+ def _source(options = {})
90
+ # build sandbox for getting the data
91
+ RubyReportable::Sandbox.new(:meta => @meta, :source => @data_source[:logic], :inputs => options[:input] || {}, :input => nil)
92
+ end
93
+
94
+ def _data(sandbox, options = {})
95
+ _filter(@filters, sandbox, options)
96
+ end
97
+
98
+ def _finalize(sandbox, options = {})
99
+ if @finalize.nil?
100
+ sandbox
101
+ else
102
+ sandbox[:inputs] = options[:input] || {}
103
+ sandbox.build(:source, @finalize)
104
+ end
105
+ end
106
+
107
+ def _output(source_data, options = {})
108
+ # build sandbox for building outputs
109
+ sandbox = RubyReportable::Sandbox.new(:meta => @meta, @data_source[:as] => nil)
110
+
111
+ source_data.inject({:results => []}) do |rows, element|
112
+ # fill sandbox with data element
113
+ sandbox[@data_source[:as]] = element
114
+
115
+ # grab outputs
116
+ rows[:results] << @outputs.inject({}) do |row, output|
117
+ row[output.name] = sandbox.instance_eval(&output.logic)
118
+ row
119
+ end
120
+
121
+ rows
122
+ end
123
+ end
124
+
125
+ def _group(group, data, options = {})
126
+ unless group.to_s.empty?
127
+ data[:results].inject({}) do |hash, element|
128
+ key = element[group]
129
+ hash[key] ||= []
130
+ hash[key] << element
131
+ hash
132
+ end
133
+ else
134
+ data
135
+ end
136
+ end
137
+
138
+ def _sort(sort, data, options = {})
139
+ unless sort.to_s.empty?
140
+ data.inject(Hash.new([])) do |hash, (group, elements)|
141
+ hash[group] = elements.sort_by {|element| element[sort]}
142
+ hash
143
+ end
144
+ else
145
+ data
146
+ end
147
+ end
148
+
149
+ def run(options = {})
150
+ options = {:input => {}}.merge(options)
151
+
152
+ # initial sandbox
153
+ sandbox = _source(options)
154
+
155
+ # apply filters to source
156
+ filtered_sandbox = _data(sandbox, options)
157
+
158
+ # finalize raw data from source
159
+ source_data = _finalize(filtered_sandbox, options).source
160
+
161
+ # {:default => [{outputs => values}]
162
+ data = _output(source_data, options)
163
+
164
+ # transform into {group => [outputs => values]}
165
+ grouped = _group(options[:group], data, options)
166
+
167
+ # sort grouped data
168
+ _sort(options[:sort], grouped, options)
169
+ end # end def run
170
+
171
+ def valid?(options = {})
172
+ options = {:input => {}}.merge(options)
173
+
174
+ # initial sandbox
175
+ sandbox = _source(options)
176
+
177
+ # add in inputs
178
+ sandbox[:inputs] = options[:input]
179
+
180
+ validity = @filters.map do |filter_name, filter|
181
+ # find input for given filter
182
+ sandbox[:input] = options[:input][filter[:key]] if options[:input].is_a?(Hash)
183
+
184
+ filter_validity = filter[:valid].nil? || sandbox.instance_eval(&filter[:valid])
185
+
186
+ if filter_validity == false
187
+ # filter failed validity test, if it's a required filter
188
+ # we return false, otherwise its optional so return true
189
+ if filter[:require]
190
+ false
191
+ else
192
+ true
193
+ end
194
+ else
195
+ true
196
+ end
197
+ end
198
+
199
+ !validity.include?(false)
200
+ end # end def valid?
201
+ end
202
+ end
@@ -0,0 +1,52 @@
1
+ module RubyReportable
2
+ class Sandbox
3
+ def metaclass
4
+ class << self; self; end
5
+ end
6
+
7
+ def initialize(_methods = {})
8
+ @values = {}
9
+
10
+ _methods.map do |key, value|
11
+ define(key, value)
12
+ end
13
+ end
14
+
15
+ def build(base, block)
16
+ @values[base] = instance_eval(&block)
17
+ self
18
+ end
19
+
20
+ def [](key)
21
+ @values[key]
22
+ end
23
+
24
+ def []=(key, value)
25
+ if value.is_a?(Proc)
26
+ @values[key] = value.call
27
+ else
28
+ @values[key] = value
29
+ end
30
+ end
31
+
32
+ def define(key, value)
33
+ if self.class.respond_to?(:define_singleton_method)
34
+ define_singleton_method(key) do
35
+ if value.is_a?(Proc)
36
+ @values[key] ||= value.call
37
+ else
38
+ @values[key] ||= value
39
+ end
40
+ end
41
+ else
42
+ metaclass.send(:define_method, key, Proc.new do
43
+ if value.is_a?(Proc)
44
+ @values[key] ||= value.call
45
+ else
46
+ @values[key] ||= value
47
+ end
48
+ end)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ module RubyReportable
2
+ class Source
3
+ def initialize
4
+ @options = {:filters => [], :as => :element}
5
+ end
6
+
7
+ def [](key)
8
+ @options[key]
9
+ end
10
+
11
+ def []=(key, value)
12
+ @options[key] = value
13
+ end
14
+
15
+ def as(variable_name)
16
+ self[:as] = variable_name
17
+ end
18
+
19
+ def logic(&block)
20
+ self[:logic] = block
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module RubyReportable
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "ruby_reportable/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "ruby_reportable"
6
+ s.version = RubyReportable::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["John 'asceth' Long"]
9
+ s.email = ["machinist@asceth.com"]
10
+ s.homepage = "http://github.com/asceth/ruby_reportable"
11
+ s.summary = "Ruby Reporting"
12
+ s.description = "Allows you to write reports that use existing ruby classes/methods to present/filter the data"
13
+
14
+ s.rubyforge_project = "ruby_reportable"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency 'rspec'
22
+ s.add_development_dependency 'rr'
23
+ end
24
+
data/spec/base_spec.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyReportable do
4
+
5
+ end
6
+
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyReportable::Filter do
4
+
5
+ context "a filter" do
6
+ before do
7
+ @filter = RubyReportable::Filter.new('G Methods')
8
+ end
9
+
10
+ it "should store variables internally" do
11
+ @filter[:logic].should == nil
12
+
13
+ @filter.key(:g)
14
+ @filter.logic do
15
+ element.include?('g')
16
+ end
17
+
18
+ @filter[:key].should == :g
19
+ @filter[:logic].should_not == nil
20
+ end
21
+
22
+ context "#require" do
23
+ it "should automatically assume it is required when no block is given" do
24
+ @filter.require
25
+
26
+ @filter[:require].should == true
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ class FooReport; include RubyReportable; end
4
+
5
+ describe RubyReportable::Report do
6
+
7
+ before do
8
+ @report = FooReport
9
+ @report.clear
10
+ end
11
+
12
+ context "#_source" do
13
+ before do
14
+ @report.source do
15
+ logic do
16
+ Object.methods
17
+ end
18
+ end
19
+ end
20
+
21
+ it "should contruct a sandbox to build up source data" do
22
+ sandbox = @report._source
23
+
24
+ sandbox.source.should == Object.methods
25
+ end
26
+ end
27
+
28
+ context "#_data" do
29
+ before do
30
+ @report.source do
31
+ logic do
32
+ Object.methods
33
+ end
34
+ end
35
+ end
36
+
37
+ it "should be able to filter on source data" do
38
+ @report.filter('G Methods') do
39
+ logic do
40
+ source.select {|element| element.to_s.include?('g')}
41
+ end
42
+ end
43
+
44
+ @report._data(@report._source).source.should == Object.methods.select {|method| method.to_s.include?('g')}
45
+ end
46
+
47
+ it "should use available input when filtering data" do
48
+ @report.filter('Filter Methods') do
49
+ key :letter
50
+
51
+ logic do
52
+ source.select {|element| element.to_s.include?(input)}
53
+ end
54
+ end
55
+
56
+ source_sandbox = @report._source
57
+ options = {:input => {:letter => 'g'}}
58
+ @report._data(source_sandbox, options).source.should == Object.methods.select {|method| method.to_s.include?('g')}
59
+
60
+ source_sandbox = @report._source
61
+ options = {:input => {:letter => 'r'}}
62
+ @report._data(source_sandbox, options).source.should == Object.methods.select {|method| method.to_s.include?('r')}
63
+ end
64
+
65
+ it "should handle multiple filters" do
66
+ @report.filter('G Methods') do
67
+ priority 0
68
+
69
+ logic do
70
+ source.select {|element| element.to_s.include?('g')}
71
+ end
72
+ end
73
+
74
+ @report.filter('R Methods') do
75
+ priority 1
76
+
77
+ logic do
78
+ source.select {|element| element.to_s.include?('r')}
79
+ end
80
+ end
81
+
82
+ source_sandbox = @report._source
83
+
84
+ @report._data(source_sandbox).source.should == Object.methods.select {|method| method.to_s.include?('g') && method.to_s.include?('r')}
85
+ end
86
+
87
+ it "should handle multiple filters in the right priority" do
88
+ @report.source do
89
+ logic do
90
+ Object.methods
91
+ end
92
+ end
93
+
94
+ @report.filter('G Methods') do
95
+ priority 0
96
+
97
+ logic do
98
+ source.map(&:to_s).select {|element| element.include?('g')}
99
+ end
100
+ end
101
+
102
+ @report.filter('R Methods') do
103
+ priority 1
104
+
105
+ logic do
106
+ source.select {|element| element.include?('r')}.map(&:to_sym)
107
+ end
108
+ end
109
+
110
+ source_sandbox = @report._source
111
+
112
+ # G Methods has to run first because otherwise Object.methods
113
+ # returns symbols and R Methods is trying to do a include? on a symbol
114
+ @report._data(source_sandbox).source.should == Object.methods.select {|method| method.to_s.include?('g') && method.to_s.include?('r')}
115
+ end
116
+ end
117
+
118
+ context "#_group" do
119
+ it "should group results" do
120
+ @report.source do
121
+ logic do
122
+ [:method]
123
+ end
124
+ end
125
+
126
+ @report.output('name') do
127
+ element
128
+ end
129
+
130
+ @report.output('letter') do
131
+ element.to_s[0]
132
+ end
133
+
134
+ source_data = @report._data(@report._source).source
135
+
136
+ @report._group('letter', @report._output(source_data)).should == {"m" => [{'name' => :method, 'letter' => 'm'}]}
137
+ end
138
+ end
139
+
140
+ context "#_sort" do
141
+ it "should sort results" do
142
+ @report.source do
143
+ logic do
144
+ Object.methods
145
+ end
146
+ end
147
+
148
+ @report.output('name') do
149
+ element
150
+ end
151
+
152
+ source_data = @report._data(@report._source).source
153
+ final = @report._sort('name', @report._output(source_data))
154
+
155
+ final.should == {:results => Object.methods.sort.map {|method| {'name' => method}}}
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyReportable::Sandbox do
4
+
5
+ context "a sandbox" do
6
+ before do
7
+ @sandbox = RubyReportable::Sandbox.new(:source => [1, 2])
8
+ end
9
+
10
+ it "should create new methods based on options" do
11
+ RubyReportable::Sandbox.new.respond_to?(:source).should == false
12
+ @sandbox.respond_to?(:source).should == true
13
+ end
14
+
15
+ it "should store the value of a defined call" do
16
+ @sandbox.source.should == [1, 2]
17
+ @sandbox[:source].should == [1, 2]
18
+ end
19
+
20
+ it "should not call a method when trying to retrieve the stored value directly" do
21
+ @sandbox[:source].should == nil
22
+ end
23
+
24
+ it "should be able to define a new method with value dynamically" do
25
+ @sandbox.define(:arbitrary, proc { Time.now })
26
+ @sandbox.respond_to?(:arbitrary).should == true
27
+ end
28
+
29
+ it "should not override a stored value with a method call" do
30
+ @sandbox[:source] = [3, 4]
31
+ @sandbox.source.should == [3, 4]
32
+ end
33
+
34
+ it "should allow you to build up a stored value" do
35
+ @sandbox[:source] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
36
+ @sandbox.build(:source, proc { source.select(&:odd?) })
37
+
38
+ @sandbox[:source].should == [1, 3, 5, 7, 9]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyReportable::Source do
4
+
5
+ context "a source" do
6
+ before do
7
+ @source = RubyReportable::Source.new
8
+ end
9
+
10
+ it "should store as and logic variables" do
11
+ @source.as(:element)
12
+ @source.logic do
13
+ Object.methods.sort
14
+ end
15
+
16
+ @source[:as].should == :element
17
+ @source[:logic].call.should == Object.methods.sort
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+ require 'rspec'
6
+ require 'ruby_reportable'
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rr
10
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_reportable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John 'asceth' Long
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rr
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Allows you to write reports that use existing ruby classes/methods to
47
+ present/filter the data
48
+ email:
49
+ - machinist@asceth.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gemtest
55
+ - .rspec
56
+ - .rvmrc
57
+ - Gemfile
58
+ - Gemfile.lock
59
+ - LICENSE
60
+ - README.md
61
+ - Rakefile
62
+ - design
63
+ - examples/object_space_report.rb
64
+ - lib/ruby_reportable.rb
65
+ - lib/ruby_reportable/base.rb
66
+ - lib/ruby_reportable/filter.rb
67
+ - lib/ruby_reportable/output.rb
68
+ - lib/ruby_reportable/report.rb
69
+ - lib/ruby_reportable/sandbox.rb
70
+ - lib/ruby_reportable/source.rb
71
+ - lib/ruby_reportable/version.rb
72
+ - ruby_reportable.gemspec
73
+ - spec/base_spec.rb
74
+ - spec/filter_spec.rb
75
+ - spec/report_spec.rb
76
+ - spec/sandbox_spec.rb
77
+ - spec/source_spec.rb
78
+ - spec/spec_helper.rb
79
+ homepage: http://github.com/asceth/ruby_reportable
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project: ruby_reportable
99
+ rubygems_version: 1.8.24
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Ruby Reporting
103
+ test_files:
104
+ - spec/base_spec.rb
105
+ - spec/filter_spec.rb
106
+ - spec/report_spec.rb
107
+ - spec/sandbox_spec.rb
108
+ - spec/source_spec.rb
109
+ - spec/spec_helper.rb