pivot_table 0.1.4 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8b35be064e1f9bfb58e308e4b702c61e5b1621f
4
- data.tar.gz: f02b0339418df01e332c6cd2743e1fcd137ec6fa
3
+ metadata.gz: 2684137254bb56ddbe7d1f32a2d505494170d38c
4
+ data.tar.gz: 1d3d224b88c1df7c8980196e463ff6788f42cddd
5
5
  SHA512:
6
- metadata.gz: 3b1630a683b93dd84c7e7687e2c52e49a43272dc81256654ebd51033cc4b0eff8b17669f43ee866e8ab7f3fc1a874e90ddd42e938e84ed0330fa7167a55eb963
7
- data.tar.gz: 18bb1571676d2a33a4ba1ac48fe7780ffa1a02015ac1479f4057862478eb9f6837656a3dfa80838cf64bb131a73c84bbff6091a057a536743e9f8380e4ef9a86
6
+ metadata.gz: e57ccdddfff53cff46227a1cce75f9640376cd08feff730a773e44f1316937609a0c9e2a5a217d804a7ca18db291901e7c6a3c736c469e4ed6acb70a618118d1
7
+ data.tar.gz: 315f28559f9ccf3d9f1addfcb5fa5e4ba58125c950a42c5c0b9cdeca575d62cae7a6341fa56790c1151ba64ddaa6a34adcf67de077e743400a9663f018867df0
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  .bundle
4
4
  Gemfile.lock
5
5
  pkg/*
6
+ tmp
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- # Pivot Table [![Build Status](https://secure.travis-ci.org/edjames/pivot_table.png)](http://travis-ci.org/edjames/pivot_table) [![Code Climate](https://codeclimate.com/github/edjames/pivot_table.png)](https://codeclimate.com/github/edjames/pivot_table)
2
-
1
+ # Pivot Table [![Build Status](https://secure.travis-ci.org/edjames/pivot_table.png)](http://travis-ci.org/edjames/pivot_table) [![Code Climate](https://codeclimate.com/github/edjames/pivot_table.png)](https://codeclimate.com/github/edjames/pivot_table) [![Dependency Status](https://gemnasium.com/edjames/pivot_table.png)](https://gemnasium.com/edjames/pivot_table)
3
2
 
4
3
  A handy tool for transforming a dataset into a spreadsheet-style pivot table.
5
4
 
@@ -103,15 +102,35 @@ If you want to get the totals for rows, columns, or the entire grid, you can pas
103
102
  g.rows[1].total
104
103
  g.grand_total
105
104
 
105
+ #### Configuration Options
106
+
107
+ You can also provide additional configuration options when instantiating your Grid. Options are provided as a hash e.g.
108
+
109
+ grid = PivotTable::Grid.new(:sort => true) do |g|
110
+ g.source_data = data
111
+ g.column_name = :quarter
112
+ g.row_name = :city
113
+ g.value_name = :sales
114
+ end
115
+
116
+ Here are the available configuration options:
117
+
118
+ ###### 1. Sort
119
+
120
+ **Usage:** `:sort => false`
121
+
122
+ **Default:** `true`
123
+
124
+ This option will automatically sort your data alphabetically based on your column and row headers. If you disable sorting your original data ordering will be preserved.
125
+
106
126
 
107
127
  ### Ruby Support
108
- ----------------
109
128
 
110
129
  * 1.9.3
111
130
  * 2.0.0
131
+ * 2.1.0
112
132
 
113
- Contributing to PivotTable
114
- ---------------------
133
+ ### Contributing to PivotTable
115
134
 
116
135
  If you want to contribute:
117
136
 
@@ -123,7 +142,6 @@ If you want to contribute:
123
142
  * Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
124
143
  * Please try not to mess with the Rakefile, version, or history.
125
144
 
126
- Copyright
127
- ---------
145
+ ### Copyright
128
146
 
129
- Copyright (c) 2013 Ed James. See LICENSE for details.
147
+ Copyright (c) 2014 Ed James. See LICENSE for details.
data/lib/pivot_table.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  $: << File.dirname(__FILE__)
2
2
 
3
- require "pivot_table/grid"
4
- require "pivot_table/cell_collection"
5
- require "pivot_table/column"
6
- require "pivot_table/row"
3
+ require 'pivot_table/configuration'
4
+ require 'pivot_table/grid'
5
+ require 'pivot_table/cell_collection'
6
+ require 'pivot_table/column'
7
+ require 'pivot_table/row'
7
8
 
8
9
  module PivotTable
9
- VERSION = "0.1.4"
10
+ VERSION = '0.2.0'
10
11
  end
@@ -0,0 +1,13 @@
1
+ module PivotTable
2
+ class Configuration
3
+
4
+ def initialize(opts = {})
5
+ @opts = opts
6
+ end
7
+
8
+ def method_missing(method_name, *arguments, &block)
9
+ @opts[method_name]
10
+ end
11
+
12
+ end
13
+ end
@@ -2,10 +2,15 @@ module PivotTable
2
2
  class Grid
3
3
 
4
4
  attr_accessor :source_data, :row_name, :column_name, :value_name
5
- attr_reader :columns, :rows, :data_grid
5
+ attr_reader :columns, :rows, :data_grid, :configuration
6
6
 
7
- def initialize(&block)
7
+ DEFAULT_OPTIONS = {
8
+ :sort => true
9
+ }
10
+
11
+ def initialize(opts = {}, &block)
8
12
  yield(self) if block_given?
13
+ @configuration = Configuration.new(DEFAULT_OPTIONS.merge(opts))
9
14
  end
10
15
 
11
16
  def build
@@ -80,7 +85,8 @@ module PivotTable
80
85
  private
81
86
 
82
87
  def headers(method)
83
- @source_data.collect { |c| c.send method }.uniq.sort
88
+ hdrs = @source_data.collect { |c| c.send method }.uniq
89
+ configuration.sort ? hdrs.sort : hdrs
84
90
  end
85
91
 
86
92
  end
data/pivot_table.gemspec CHANGED
@@ -23,5 +23,5 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_development_dependency "rspec", "~> 2.14"
25
25
  s.add_development_dependency "growl", "~> 1.0"
26
- s.add_development_dependency "guard-rspec", "~> 4.0"
26
+ s.add_development_dependency "guard-rspec", "~> 4.2"
27
27
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ module PivotTable
4
+ describe Configuration do
5
+
6
+ subject { described_class.new opts }
7
+
8
+ let(:opts) { { :sort => true, :other_setting => 'on' } }
9
+
10
+ its(:sort) { should be_true }
11
+ its(:other_setting) { should == 'on' }
12
+
13
+ context 'when setting does not exist' do
14
+ its(:i_do_not_exist) { should be_nil }
15
+ end
16
+
17
+ end
18
+ end
@@ -2,41 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  module PivotTable
4
4
  describe Grid do
5
- def build_object(id, row, column)
6
- OpenStruct.new id: id, row_name: row, column_name: column
7
- end
8
-
9
- let(:d1) { build_object(1, 'r1', 'c1') }
10
- let(:d2) { build_object(2, 'r1', 'c2') }
11
- let(:d3) { build_object(3, 'r1', 'c3') }
12
- let(:d4) { build_object(4, 'r2', 'c1') }
13
- let(:d5) { build_object(5, 'r2', 'c2') }
14
- let(:d6) { build_object(6, 'r2', 'c3') }
15
-
16
- let(:data) { [d1, d2, d3, d4, d5, d6] }
17
-
18
- let(:column_headers) { %w(c1 c2 c3) }
19
- let(:row_headers) { %w(r1 r2) }
20
- let(:row_0) { [d1, d2, d3] }
21
- let(:row_1) { [d4, d5, d6] }
22
- let(:column_0) { [d1, d4] }
23
- let(:column_1) { [d2, d5] }
24
- let(:column_2) { [d3, d6] }
25
- let(:column_totals) { [d1.id + d4.id, d2.id + d5.id, d3.id + d6.id] }
26
- let(:row_totals) { [d1.id + d2.id + d3.id, d4.id + d5.id + d6.id] }
27
- let(:grand_total) { d1.id + d2.id + d3.id + d4.id + d5.id + d6.id }
28
-
29
- let(:instance) do
30
- Grid.new do |g|
31
- g.source_data = data
32
- g.row_name = :row_name
33
- g.column_name = :column_name
34
- g.value_name = :id
35
- end
36
- end
37
5
 
38
6
  context 'accessors' do
39
- subject { Grid.new }
40
7
  it { should respond_to :source_data }
41
8
  it { should respond_to :row_name }
42
9
  it { should respond_to :column_name }
@@ -45,85 +12,83 @@ module PivotTable
45
12
  it { should respond_to :grand_total }
46
13
  end
47
14
 
48
- describe 'build' do
49
- subject { instance.build }
50
- its(:class) { should == Grid }
51
- end
52
-
53
- describe 'columns' do
54
- let(:build_result) { instance.build }
55
- specify { build_result.columns.length.should == 3 }
56
-
57
- context 'column headers' do
58
- subject { build_result.column_headers }
59
- it { should == column_headers }
60
- end
61
-
62
- context '1st column' do
63
- subject { build_result.columns[0] }
64
- its(:header) { should == column_headers[0] }
65
- its(:data) { should == column_0 }
66
- its(:total) { should == column_totals[0] }
67
- end
15
+ let(:d1) { build_data_object(1, 'r1', 'c1') }
16
+ let(:d2) { build_data_object(2, 'r1', 'c2') }
17
+ let(:d3) { build_data_object(3, 'r1', 'c3') }
18
+ let(:d4) { build_data_object(4, 'r2', 'c1') }
19
+ let(:d5) { build_data_object(5, 'r2', 'c2') }
20
+ let(:d6) { build_data_object(6, 'r2', 'c3') }
68
21
 
69
- context '2nd column' do
70
- subject { build_result.columns[1] }
71
- its(:header) { should == column_headers[1] }
72
- its(:data) { should == column_1 }
73
- its(:total) { should == column_totals[1] }
74
- end
22
+ let(:sorted_data) { [d1, d2, d3, d4, d5, d6] }
23
+ let(:unsorted_data) { [d6, d4, d5, d3, d2, d1] }
75
24
 
76
- context '3rd column' do
77
- subject { build_result.columns[2] }
78
- its(:header) { should == column_headers[2] }
79
- its(:data) { should == column_2 }
80
- its(:total) { should == column_totals[2] }
25
+ let(:instance) do
26
+ described_class.new(config) do |g|
27
+ g.source_data = data
28
+ g.row_name = :row_name
29
+ g.column_name = :column_name
30
+ g.value_name = :id
81
31
  end
82
32
  end
83
33
 
84
- describe 'rows' do
85
- let(:build_result) { instance.build }
86
- specify { build_result.rows.length.should == 2 }
87
-
88
- context 'row headers' do
89
- subject { build_result.row_headers }
90
- it { should == row_headers }
91
- end
92
-
93
- context '1st row' do
94
- subject { build_result.rows[0] }
95
- its(:header) { should == row_headers[0] }
96
- its(:data) { should == row_0 }
97
- its(:total) { should == row_totals[0] }
98
- end
99
-
100
- context '2nd row' do
101
- subject { build_result.rows[1] }
102
- its(:header) { should == row_headers[1] }
103
- its(:data) { should == row_1 }
104
- its(:total) { should == row_totals[1] }
105
- end
34
+ context 'when data is already sorted' do
35
+ let(:config) { {} }
36
+ let(:data) { sorted_data }
37
+
38
+ let(:column_headers) { %w(c1 c2 c3) }
39
+ let(:row_headers) { %w(r1 r2) }
40
+ let(:row_0) { [d1, d2, d3] }
41
+ let(:row_1) { [d4, d5, d6] }
42
+ let(:column_0) { [d1, d4] }
43
+ let(:column_1) { [d2, d5] }
44
+ let(:column_2) { [d3, d6] }
45
+ let(:column_totals) { [d1.id + d4.id, d2.id + d5.id, d3.id + d6.id] }
46
+ let(:row_totals) { [d1.id + d2.id + d3.id, d4.id + d5.id + d6.id] }
47
+ let(:grand_total) { d1.id + d2.id + d3.id + d4.id + d5.id + d6.id }
48
+
49
+ it_behaves_like 'a collection of columns'
50
+ it_behaves_like 'a collection of rows'
51
+ it_behaves_like 'a data grid'
106
52
  end
107
53
 
108
- describe 'data grid' do
109
- let(:build_result) { instance.build }
110
-
111
- context 'preparing the grid' do
112
- subject { build_result.prepare_grid }
113
- it { should == [[nil, nil, nil], [nil, nil, nil]] }
114
- end
115
-
116
- context 'populating the grid' do
117
- subject { build_result.data_grid }
118
- it { should == [[d1, d2, d3], [d4, d5, d6]] }
119
- end
54
+ context 'sorting unordered data' do
55
+ let(:config) { { :sort => true } }
56
+ let(:data) { unsorted_data }
57
+
58
+ let(:column_headers) { %w(c1 c2 c3) }
59
+ let(:row_headers) { %w(r1 r2) }
60
+ let(:row_0) { [d1, d2, d3] }
61
+ let(:row_1) { [d4, d5, d6] }
62
+ let(:column_0) { [d1, d4] }
63
+ let(:column_1) { [d2, d5] }
64
+ let(:column_2) { [d3, d6] }
65
+ let(:column_totals) { [d1.id + d4.id, d2.id + d5.id, d3.id + d6.id] }
66
+ let(:row_totals) { [d1.id + d2.id + d3.id, d4.id + d5.id + d6.id] }
67
+ let(:grand_total) { d1.id + d2.id + d3.id + d4.id + d5.id + d6.id }
68
+
69
+ it_behaves_like 'a collection of columns'
70
+ it_behaves_like 'a collection of rows'
71
+ it_behaves_like 'a data grid'
72
+ end
120
73
 
121
- context 'totals' do
122
- subject { build_result }
123
- its(:column_totals) { should == column_totals }
124
- its(:row_totals) { should == row_totals }
125
- its(:grand_total) { should == grand_total }
126
- end
74
+ context 'keep original data ordering' do
75
+ let(:config) { { :sort => false } }
76
+ let(:data) { unsorted_data }
77
+
78
+ let(:column_headers) { %w(c3 c1 c2) }
79
+ let(:row_headers) { %w(r2 r1) }
80
+ let(:row_0) { [d6, d4, d5] }
81
+ let(:row_1) { [d3, d1, d2] }
82
+ let(:column_0) { [d6, d3] }
83
+ let(:column_1) { [d4, d1] }
84
+ let(:column_2) { [d5, d2] }
85
+ let(:column_totals) { [d6.id + d3.id, d4.id + d1.id, d5.id + d2.id] }
86
+ let(:row_totals) { [d6.id + d4.id + d5.id, d3.id + d2.id + d1.id] }
87
+ let(:grand_total) { d1.id + d2.id + d3.id + d4.id + d5.id + d6.id }
88
+
89
+ it_behaves_like 'a collection of columns'
90
+ it_behaves_like 'a collection of rows'
91
+ it_behaves_like 'a data grid'
127
92
  end
128
93
  end
129
94
  end
data/spec/spec_helper.rb CHANGED
@@ -11,4 +11,6 @@ Dir["./spec/support/**/*.rb"].each {|f| require f}
11
11
 
12
12
  RSpec.configure do |config|
13
13
 
14
+ config.include Helpers
15
+
14
16
  end
@@ -0,0 +1,7 @@
1
+ module Helpers
2
+
3
+ def build_data_object(id, row, column)
4
+ OpenStruct.new id: id, row_name: row, column_name: column
5
+ end
6
+
7
+ end
@@ -1,5 +1,4 @@
1
1
  shared_examples "a cell collection" do
2
-
3
2
  it { should respond_to :header }
4
3
  it { should respond_to :data }
5
4
  it { should respond_to :value_name }
@@ -16,5 +15,4 @@ shared_examples "a cell collection" do
16
15
  its(:data) { should == attrs[:data] }
17
16
  its(:value_name) { should == attrs[:value_name] }
18
17
  end
19
-
20
18
  end
@@ -0,0 +1,30 @@
1
+ shared_examples 'a collection of columns' do
2
+ let(:build_result) { instance.build }
3
+ specify { build_result.columns.length.should == 3 }
4
+
5
+ context 'column headers' do
6
+ subject { build_result.column_headers }
7
+ it { should == column_headers }
8
+ end
9
+
10
+ context '1st column' do
11
+ subject { build_result.columns[0] }
12
+ its(:header) { should == column_headers[0] }
13
+ its(:data) { should == column_0 }
14
+ its(:total) { should == column_totals[0] }
15
+ end
16
+
17
+ context '2nd column' do
18
+ subject { build_result.columns[1] }
19
+ its(:header) { should == column_headers[1] }
20
+ its(:data) { should == column_1 }
21
+ its(:total) { should == column_totals[1] }
22
+ end
23
+
24
+ context '3rd column' do
25
+ subject { build_result.columns[2] }
26
+ its(:header) { should == column_headers[2] }
27
+ its(:data) { should == column_2 }
28
+ its(:total) { should == column_totals[2] }
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ shared_examples 'a collection of rows' do
2
+ let(:build_result) { instance.build }
3
+ specify { build_result.rows.length.should == 2 }
4
+
5
+ context 'row headers' do
6
+ subject { build_result.row_headers }
7
+ it { should == row_headers }
8
+ end
9
+
10
+ context '1st row' do
11
+ subject { build_result.rows[0] }
12
+ its(:header) { should == row_headers[0] }
13
+ its(:data) { should == row_0 }
14
+ its(:total) { should == row_totals[0] }
15
+ end
16
+
17
+ context '2nd row' do
18
+ subject { build_result.rows[1] }
19
+ its(:header) { should == row_headers[1] }
20
+ its(:data) { should == row_1 }
21
+ its(:total) { should == row_totals[1] }
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ shared_examples 'a data grid' do
2
+ let(:build_result) { instance.build }
3
+
4
+ context 'preparing the grid' do
5
+ subject { build_result.prepare_grid }
6
+ it { should == [[nil, nil, nil], [nil, nil, nil]] }
7
+ end
8
+
9
+ context 'populating the grid' do
10
+ subject { build_result.data_grid }
11
+ it { should == [row_0, row_1] }
12
+ end
13
+
14
+ context 'totals' do
15
+ subject { build_result }
16
+ its(:column_totals) { should == column_totals }
17
+ its(:row_totals) { should == row_totals }
18
+ its(:grand_total) { should == grand_total }
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pivot_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ed James
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-30 00:00:00.000000000 Z
11
+ date: 2014-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '4.0'
47
+ version: '4.2'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '4.0'
54
+ version: '4.2'
55
55
  description: Transform an ActiveRecord-ish data set into a pivot table of objects
56
56
  email: ed.james.email@gmail.com
57
57
  executables: []
@@ -70,14 +70,20 @@ files:
70
70
  - lib/pivot_table.rb
71
71
  - lib/pivot_table/cell_collection.rb
72
72
  - lib/pivot_table/column.rb
73
+ - lib/pivot_table/configuration.rb
73
74
  - lib/pivot_table/grid.rb
74
75
  - lib/pivot_table/row.rb
75
76
  - pivot_table.gemspec
76
77
  - spec/pivot_table/column_spec.rb
78
+ - spec/pivot_table/configuration_spec.rb
77
79
  - spec/pivot_table/grid_spec.rb
78
80
  - spec/pivot_table/row_spec.rb
79
81
  - spec/spec_helper.rb
80
- - spec/support/shared_examples.rb
82
+ - spec/support/helpers.rb
83
+ - spec/support/shared_examples_for_a_cell_collection_.rb
84
+ - spec/support/shared_examples_for_a_collection_of_columns.rb
85
+ - spec/support/shared_examples_for_a_collection_of_rows.rb
86
+ - spec/support/shared_examples_for_a_data_grid.rb
81
87
  homepage: https://github.com/edjames/pivot_table
82
88
  licenses: []
83
89
  metadata: {}
@@ -97,13 +103,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
103
  version: '0'
98
104
  requirements: []
99
105
  rubyforge_project: pivot_table
100
- rubygems_version: 2.0.3
106
+ rubygems_version: 2.1.11
101
107
  signing_key:
102
108
  specification_version: 4
103
- summary: pivot_table-0.1.4
109
+ summary: pivot_table-0.2.0
104
110
  test_files:
105
111
  - spec/pivot_table/column_spec.rb
112
+ - spec/pivot_table/configuration_spec.rb
106
113
  - spec/pivot_table/grid_spec.rb
107
114
  - spec/pivot_table/row_spec.rb
108
115
  - spec/spec_helper.rb
109
- - spec/support/shared_examples.rb
116
+ - spec/support/helpers.rb
117
+ - spec/support/shared_examples_for_a_cell_collection_.rb
118
+ - spec/support/shared_examples_for_a_collection_of_columns.rb
119
+ - spec/support/shared_examples_for_a_collection_of_rows.rb
120
+ - spec/support/shared_examples_for_a_data_grid.rb