tablinate 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +171 -0
- data/Rakefile +1 -0
- data/lib/tablinate.rb +30 -0
- data/lib/tablinate/adapters/active_record.rb +12 -0
- data/lib/tablinate/adapters/array.rb +5 -0
- data/lib/tablinate/railtie.rb +10 -0
- data/lib/tablinate/table.rb +19 -0
- data/lib/tablinate/table/tbody.rb +28 -0
- data/lib/tablinate/table/thead.rb +18 -0
- data/lib/tablinate/tag.rb +61 -0
- data/lib/tablinate/version.rb +3 -0
- data/spec/spec_functions.rb +26 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/table/tbody_spec.rb +48 -0
- data/spec/table/thead_spec.rb +49 -0
- data/spec/table_spec.rb +11 -0
- data/spec/tablinate/active_record_spec.rb +17 -0
- data/spec/tablinate/array_spec.rb +24 -0
- data/spec/tablinate_spec.rb +67 -0
- data/spec/tag_spec.rb +59 -0
- data/tablinate.gemspec +21 -0
- data/views/index.haml +2 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a09c49e4cb9191e805d0bd10005bc72bbb7332e5
|
4
|
+
data.tar.gz: a7b0ff95339764772d95252f9f7288cae2f8a522
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9e1df452921b1a6d3d0b8b0d9eaf70dfe2558a9a5b6ee33bbb1241096b32120ec3a45e9d75795fc2907617828220581809eb2992c209d49a149dba69fc13de8
|
7
|
+
data.tar.gz: 74b550e824bb56a226e59a62012ab175983db2798d51a6656978a42d2ccf741729850b0546d1aead05affd0404b604aa20a5caa4b7740e444ef167321cc2699d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Kevin Collette and Isabelle Carter
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
# Tablinate
|
2
|
+
|
3
|
+
## Author(s)
|
4
|
+
|
5
|
+
* [Isabelle Carter](http://github.com/ibnc)
|
6
|
+
* [Kevin Collette](http://github.com/collettiquette)
|
7
|
+
|
8
|
+
## Note
|
9
|
+
|
10
|
+
This project is dead. It was something I made years ago with friends when we were still not great programmers. It was never a good idea, but it was fun to write none the less. This is still up because I see no reason to take it down, and I occasionally use this repo as a test repo on other projects.
|
11
|
+
|
12
|
+
## Description
|
13
|
+
|
14
|
+
Tablinate is a ruby gem that takes arrays of hashes, ActiveRecord::Relation objects, or a JSON array of hashes, and converts them into html tables. It is intended for use in small projects or applications whose schemas are closely related to standard table formats.
|
15
|
+
|
16
|
+
## Install
|
17
|
+
|
18
|
+
gem install tablinate
|
19
|
+
|
20
|
+
## Sample Sinatra Code:
|
21
|
+
|
22
|
+
### 1) app.rb
|
23
|
+
|
24
|
+
require 'sinatra'
|
25
|
+
require 'tablinate'
|
26
|
+
|
27
|
+
get '/' do
|
28
|
+
@employees = [
|
29
|
+
{ :id => '1', :first_name => "Matt", :last_name => "Smith", :title => "Time Lord" },
|
30
|
+
{ :id => '2', :first_name => "Jack", :last_name => "Harkness", :title => "Time Agent" },
|
31
|
+
{ :id => '3', :first_name => "Tom", :last_name => "Baker", :title => "Time Lord" },
|
32
|
+
{ :id => '4', :first_name => "David", :last_name => "Tennant", :title => "Time Lord" },
|
33
|
+
{ :id => '5', :first_name => "Christopher", :last_name => "Eccleston", :title => "Time Lord" }
|
34
|
+
]
|
35
|
+
haml :index
|
36
|
+
end
|
37
|
+
|
38
|
+
### 2) views/index.haml
|
39
|
+
|
40
|
+
%body
|
41
|
+
= @employees.tablinate()
|
42
|
+
|
43
|
+
### 3) view-source:http://localhost:4567/
|
44
|
+
|
45
|
+
<body>
|
46
|
+
<table>
|
47
|
+
<thead>
|
48
|
+
<tr>
|
49
|
+
<th>id</th>
|
50
|
+
<th>first_name</th>
|
51
|
+
<th>last_name</th>
|
52
|
+
<th>title</th>
|
53
|
+
</thead>
|
54
|
+
<tbody>
|
55
|
+
<tr>
|
56
|
+
<td>1</td>
|
57
|
+
<td>Matt</td>
|
58
|
+
<td>Smith</td>
|
59
|
+
<td>Time Lord</td>
|
60
|
+
</tr>
|
61
|
+
<tr>
|
62
|
+
<td>2</td>
|
63
|
+
<td>Jack</td>
|
64
|
+
<td>Harkness</td>
|
65
|
+
<td>Time Agent</td>
|
66
|
+
</tr>
|
67
|
+
<tr>
|
68
|
+
<td>3</td>
|
69
|
+
<td>Tom</td>
|
70
|
+
<td>Baker</td>
|
71
|
+
<td>Time Lord</td>
|
72
|
+
</tr>
|
73
|
+
<tr>
|
74
|
+
<td>4</td>
|
75
|
+
<td>David</td>
|
76
|
+
<td>Tennant</td>
|
77
|
+
<td>Time Lord</td>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<td>5</td>
|
81
|
+
<td>Christopher</td>
|
82
|
+
<td>Eccleston</td>
|
83
|
+
<td>Time Lord</td>
|
84
|
+
</tr>
|
85
|
+
</tbody>
|
86
|
+
</table>
|
87
|
+
</body>
|
88
|
+
|
89
|
+
## Options
|
90
|
+
|
91
|
+
Because it uses normal html markup, tablinated tables are easily styled using CSS, Sass, etc. That being said, tablinate is configurable via an options hash. The hash can style the table or add classes to it. For example:
|
92
|
+
|
93
|
+
### views/index.haml
|
94
|
+
|
95
|
+
%body
|
96
|
+
=@employees.tablinate( { :table => { :border => 1, :class => 'fluid' }, :tbody => { :class => 'foo' } } )
|
97
|
+
|
98
|
+
### view-source:http://localhost:4567/
|
99
|
+
|
100
|
+
<body>
|
101
|
+
<table border='1' class='fluid'>
|
102
|
+
<thead>
|
103
|
+
<tr>
|
104
|
+
<th>id</th>
|
105
|
+
<th>first_name</th>
|
106
|
+
<th>last_name</th>
|
107
|
+
<th>title</th>
|
108
|
+
</thead>
|
109
|
+
<tbody class='foo'>
|
110
|
+
<tr>
|
111
|
+
<td>1</td>
|
112
|
+
<td>Matt</td>
|
113
|
+
...
|
114
|
+
...
|
115
|
+
### Further notes on options
|
116
|
+
|
117
|
+
Options are highly expandable, and support many useful notations. For example:
|
118
|
+
|
119
|
+
@table_params = {
|
120
|
+
:table => { :class => "table" },
|
121
|
+
:tbody => {
|
122
|
+
:tr => { :class => [ 'class1', 'class2', 'class3' ], :id => 'meow' },
|
123
|
+
:td => { :class => 'row', :id => [1,2,3] }
|
124
|
+
}
|
125
|
+
}
|
126
|
+
@table = [
|
127
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
128
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
129
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
130
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' }
|
131
|
+
]
|
132
|
+
|
133
|
+
@table.tablinate(@table_params)
|
134
|
+
|
135
|
+
<table class='table'>
|
136
|
+
<thead>
|
137
|
+
<tr>
|
138
|
+
<th>column1</th>
|
139
|
+
<th>column2</th>
|
140
|
+
<th>column3</th>
|
141
|
+
</tr>
|
142
|
+
</thead>
|
143
|
+
<tbody>
|
144
|
+
<tr class='class1' id='meow'>
|
145
|
+
<td class='row' id='1'>value1</td>
|
146
|
+
<td class='row' id='2'>value2</td>
|
147
|
+
<td class='row' id='3'>value3</td>
|
148
|
+
</tr>
|
149
|
+
<tr class='class2' id='meow'>
|
150
|
+
<td class='row' id='1'>value1</td>
|
151
|
+
<td class='row' id='2'>value2</td>
|
152
|
+
<td class='row' id='3'>value3</td>
|
153
|
+
</tr>
|
154
|
+
<tr class='class3' id='meow'>
|
155
|
+
<td class='row' id='1'>value1</td>
|
156
|
+
<td class='row' id='2'>value2</td>
|
157
|
+
<td class='row' id='3'>value3</td>
|
158
|
+
</tr>
|
159
|
+
<tr class='class1' id='meow'>
|
160
|
+
<td class='row' id='1'>value1</td>
|
161
|
+
<td class='row' id='2'>value2</td>
|
162
|
+
<td class='row' id='3'>value3</td>
|
163
|
+
</tr>
|
164
|
+
</tbody>
|
165
|
+
</table>
|
166
|
+
### Haml note
|
167
|
+
|
168
|
+
When using haml, you may need to unescape html tags by:
|
169
|
+
|
170
|
+
%body
|
171
|
+
!= [ { ... }, ... ].tablinate(...)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/tablinate.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'tablinate/tag'
|
3
|
+
require 'tablinate/table/thead'
|
4
|
+
require 'tablinate/table/tbody'
|
5
|
+
require 'tablinate/table'
|
6
|
+
require 'tablinate/adapters/array'
|
7
|
+
## Thoughts:
|
8
|
+
# Support column summing?
|
9
|
+
# TODO: Support hidden columns?
|
10
|
+
module Tablinate
|
11
|
+
#turns an ActiveRecord::Relation into an array of hashes.
|
12
|
+
def self.generate_table(objects, params={})
|
13
|
+
Table.new(self.parse_objects(objects), params)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def self.parse_objects(objects)
|
18
|
+
if objects.class == String then
|
19
|
+
return JSON.parse(objects)
|
20
|
+
elsif objects.class.to_s == "ActiveRecord::Relation"
|
21
|
+
return objects.collect{ |x| x.attributes }
|
22
|
+
else
|
23
|
+
return objects
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if defined?(Rails::Railtie)
|
29
|
+
require 'tablinate/railtie'
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Table < Tag
|
2
|
+
include Thead
|
3
|
+
include Tbody
|
4
|
+
|
5
|
+
def initialize(values, params={})
|
6
|
+
thead = build_head(values[0].keys, thead_params(params))
|
7
|
+
tbody = build_body(values, tbody_params(params))
|
8
|
+
super("table", "", params, [thead, tbody])
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def thead_params params
|
13
|
+
params ? params.delete(:thead) : {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def tbody_params params
|
17
|
+
params ? params.delete(:tbody) : {}
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Tbody
|
2
|
+
def build_body(values, params={})
|
3
|
+
tr_params = params ? params.delete(:tr) : {}
|
4
|
+
tbody = Tag.new("tbody", "", params)
|
5
|
+
tbody.children.concat build_body_rows(values, tr_params)
|
6
|
+
return tbody
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_body_rows(rows, params={})
|
10
|
+
td_params = params ? params.delete(:td) : {}
|
11
|
+
trs = []
|
12
|
+
rows.each do |row|
|
13
|
+
tr = Tag.new("tr", "", params)
|
14
|
+
tr.children.concat build_row_entries(row, td_params)
|
15
|
+
trs << tr
|
16
|
+
end
|
17
|
+
trs
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_row_entries(row, params={})
|
21
|
+
tds = []
|
22
|
+
row.each do |key, value|
|
23
|
+
td = Tag.new("td", value, params)
|
24
|
+
tds << td
|
25
|
+
end
|
26
|
+
return tds
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Thead
|
2
|
+
def build_head(columns, params={})
|
3
|
+
tr_params = params ? params.delete(:tr) : {}
|
4
|
+
thead = Tag.new("thead", "", params)
|
5
|
+
thead.children << build_head_rows(columns, tr_params)
|
6
|
+
thead
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_head_rows(columns, params={})
|
10
|
+
th_params = params ? params.delete(:th) : {}
|
11
|
+
tr = Tag.new("tr", "", params)
|
12
|
+
columns.each do |column|
|
13
|
+
th = Tag.new("th", column, th_params)
|
14
|
+
tr.children << th
|
15
|
+
end
|
16
|
+
tr
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Tag
|
2
|
+
attr_reader :name
|
3
|
+
attr_accessor :children, :text, :attributes
|
4
|
+
|
5
|
+
def initialize(name, text="", attributes={}, children=[])
|
6
|
+
@name = name.to_sym
|
7
|
+
@attributes = attributes || {}
|
8
|
+
@children = children || []
|
9
|
+
@text = text.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s(offset=0)
|
13
|
+
build_open_tag(offset) + text + add_sub_tags + build_close_tag
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_html
|
17
|
+
format_html(to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def build_close_tag
|
22
|
+
"</#{name}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_sub_tags
|
26
|
+
children.map.with_index {|tag, i| tag.to_s(i) }.join("")
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_open_tag offset
|
30
|
+
attributes = attributes_to_html(offset)
|
31
|
+
"<#{name}#{attributes.empty? ? '' : ' '}" + attributes + ">"
|
32
|
+
end
|
33
|
+
|
34
|
+
def attributes_to_html(offset)
|
35
|
+
attributes.map do |key,value|
|
36
|
+
case value
|
37
|
+
when String
|
38
|
+
"#{key}='#{value}'"
|
39
|
+
when Symbol
|
40
|
+
"#{key}='#{value}'"
|
41
|
+
when Array
|
42
|
+
"#{key}='#{value[offset % value.count]}'"
|
43
|
+
end
|
44
|
+
end.join(" ")
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_html(html)
|
48
|
+
#Finds html tags via regex and adds whitespace so
|
49
|
+
#that the table doesn't look disgusting in the
|
50
|
+
#source code.
|
51
|
+
tags = html.scan(%r{</?[^>]+?>}).uniq
|
52
|
+
tags.each do |tag|
|
53
|
+
if tag.length > 5 || tag.include?("/") || tag.include?("tr>") then
|
54
|
+
html.gsub!(tag,"#{tag}\n")
|
55
|
+
else
|
56
|
+
html.gsub!(tag,"\s\s#{tag}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
return html
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
def objects
|
2
|
+
[
|
3
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
4
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
5
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
6
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' }
|
7
|
+
]
|
8
|
+
end
|
9
|
+
|
10
|
+
def params
|
11
|
+
{
|
12
|
+
:class => "eek", :id => 'rawr',
|
13
|
+
:thead => {
|
14
|
+
:class => "head",
|
15
|
+
:id => 2,
|
16
|
+
:th => { :class => "1",
|
17
|
+
:tr => { :class => "class1", :id => [1,2] }
|
18
|
+
}
|
19
|
+
},
|
20
|
+
:tbody => {
|
21
|
+
:tr => { :class => [ 'class1', 'class2', 'class3' ], :id => 'id-2',
|
22
|
+
:td => { :class => 'rawr', :id => [1,2,3], :foo => :bar }
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyClass
|
4
|
+
extend Tbody
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "table", Tbody do
|
8
|
+
subject { DummyClass }
|
9
|
+
|
10
|
+
context "given params" do
|
11
|
+
#TODO rewrite this test it sucks, but it ensures we keep building it right.
|
12
|
+
it "should construct the table body" do
|
13
|
+
body = subject.build_body(objects, params[:tbody])
|
14
|
+
body.to_s.should eq(
|
15
|
+
"<tbody><tr class='class1' id='id-2'><td class='rawr' id='1' foo='bar'>value1</td><td class='rawr' id='2' foo='bar'>value2</td><td class='rawr' id='3' foo='bar'>value3</td></tr><tr class='class2' id='id-2'><td class='rawr' id='1' foo='bar'>value1</td><td class='rawr' id='2' foo='bar'>value2</td><td class='rawr' id='3' foo='bar'>value3</td></tr><tr class='class3' id='id-2'><td class='rawr' id='1' foo='bar'>value1</td><td class='rawr' id='2' foo='bar'>value2</td><td class='rawr' id='3' foo='bar'>value3</td></tr><tr class='class1' id='id-2'><td class='rawr' id='1' foo='bar'>value1</td><td class='rawr' id='2' foo='bar'>value2</td><td class='rawr' id='3' foo='bar'>value3</td></tr></tbody>")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should construct the table rows" do
|
19
|
+
rows = subject.build_body_rows(objects, params[:tbody])
|
20
|
+
rows.class.should == Array
|
21
|
+
rows.each { |row| row.class.should == Tag }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "shoulid construct the entries for a row" do
|
25
|
+
entries = subject.build_row_entries(objects[0], params[:tbody])
|
26
|
+
entries.class.should == Array
|
27
|
+
entries.each { |entry| entry.class.should == Tag }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "without params" do
|
32
|
+
it "should construct the table body" do
|
33
|
+
subject.build_body(objects).class.should == Tag
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should construct the table rows" do
|
37
|
+
rows = subject.build_body_rows(objects)
|
38
|
+
rows.class.should == Array
|
39
|
+
rows.each { |row| row.class.should == Tag }
|
40
|
+
end
|
41
|
+
|
42
|
+
it "shoulid construct the entries for a row" do
|
43
|
+
entries = subject.build_row_entries(objects[0])
|
44
|
+
entries.class.should == Array
|
45
|
+
entries.each { |entry| entry.class.should == Tag }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyClass
|
4
|
+
extend Thead
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "table", Thead do
|
8
|
+
subject { DummyClass }
|
9
|
+
|
10
|
+
context "given params" do
|
11
|
+
it "should construct the table head" do
|
12
|
+
thead = subject.build_head(objects[0].keys, params)
|
13
|
+
thead.class.should == Tag
|
14
|
+
thead.to_html.scan(/<([a-zA-Z]+) ([a-zA-Z]+=\'.*?\'+)>/).each do |tag|
|
15
|
+
name = tag[0]
|
16
|
+
next if name == "thead"
|
17
|
+
params[:thead][name.to_sym].each do |param, value|
|
18
|
+
if value.class == Array then
|
19
|
+
value.map do |v|
|
20
|
+
tag[1].include?("#{param.to_s}=\'#{v}\'")
|
21
|
+
end.include?(true).should be_true
|
22
|
+
else
|
23
|
+
tag[1].include?("#{param.to_s}=\'#{value}\'").should == true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should construct the table head rows" do
|
30
|
+
head_rows = subject.build_head_rows(objects[0], params[:thead])
|
31
|
+
head_rows.class.should == Tag
|
32
|
+
head_rows.name.should == :tr
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "without params" do
|
37
|
+
it "should construct the table head" do
|
38
|
+
head = subject.build_head(objects[0])
|
39
|
+
head.class.should == Tag
|
40
|
+
head.name.should == :thead
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should construct the table head rows" do
|
44
|
+
head_rows = subject.build_head_rows(objects[0])
|
45
|
+
head_rows.class.should == Tag
|
46
|
+
head_rows.name.should == :tr
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/table_spec.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "An instance of", Table do
|
4
|
+
let(:values) { [{foo: "bar", bar: "baz"}] }
|
5
|
+
subject { Table.new(values, {thead: {tr: {th: {bar: ["t4", "t5"]}}},tbody: {tr: {td: { foo: ["t1", "t2"]}}}}) }
|
6
|
+
|
7
|
+
it "should build the table with children elements" do
|
8
|
+
subject.to_s.should eq "<table><thead><tr><th bar='t4'>foo</th><th bar='t5'>bar</th></tr></thead><tbody><tr><td foo='t1'>bar</td><td foo='t2'>baz</td></tr></tbody></table>"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
require 'active_record'
|
3
|
+
require 'spec_helper'
|
4
|
+
require File.dirname(__FILE__)+"/../../lib/tablinate/adapters/active_record"
|
5
|
+
describe "An instance of", ActiveRecord::Relation do
|
6
|
+
#subject { need to stub out ActiveRecord::Relation somehow }
|
7
|
+
describe "#tablinate" do
|
8
|
+
before do
|
9
|
+
subject.should_receive(:to_a)
|
10
|
+
Tablinate.should_receive(:generate_table)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should call tablinate and pass itself" do
|
14
|
+
subject.tablinate
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "An instance of", Array do
|
4
|
+
subject do
|
5
|
+
[
|
6
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
7
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
8
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' },
|
9
|
+
{ :column1 => 'value1', :column2 => 'value2', :column3 => 'value3' }
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#tablinate" do
|
14
|
+
before do
|
15
|
+
Tablinate.should_receive(:generate_table) do |objects, params|
|
16
|
+
objects.should == subject
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should call generate_table and pass itself and pass the params" do
|
21
|
+
subject.tablinate
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tablinate do
|
4
|
+
subject { Tablinate }
|
5
|
+
|
6
|
+
context "given an array of hashes" do
|
7
|
+
context "and a params hash" do
|
8
|
+
it "should genderate an html table" do
|
9
|
+
table = subject.generate_table(objects, params)
|
10
|
+
#using nokogiri to ensure the markup is correct
|
11
|
+
doc = Nokogiri::XML(table.to_s)
|
12
|
+
doc.errors.should == []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "and no a params hash" do
|
17
|
+
it "should generate an html table" do
|
18
|
+
table = subject.generate_table(objects)
|
19
|
+
doc = Nokogiri::XML(table.to_s)
|
20
|
+
doc.errors.should == []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "given an ActiveRecord::Relation" do
|
26
|
+
let(:ar_objects) { ActiveRecord::Relation.new }
|
27
|
+
|
28
|
+
before do
|
29
|
+
ActiveRecord::Relation.any_instance.stub(:collect) { objects }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "and a params hash" do
|
33
|
+
it "should genderate an html table" do
|
34
|
+
table = subject.generate_table(ar_objects, params)
|
35
|
+
#using nokogiri to ensure the markup is correct
|
36
|
+
doc = Nokogiri::XML(table.to_s)
|
37
|
+
doc.errors.should == []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "and no a params hash" do
|
42
|
+
it "should generate an html table" do
|
43
|
+
table = subject.generate_table(ar_objects)
|
44
|
+
doc = Nokogiri::XML(table.to_s)
|
45
|
+
doc.errors.should == []
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "given a JSON hash" do
|
51
|
+
context "and a params hash" do
|
52
|
+
it "should generate an html table" do
|
53
|
+
table = subject.generate_table(objects.to_json, params)
|
54
|
+
doc = Nokogiri::XML(table.to_s)
|
55
|
+
doc.errors.should == []
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "and no params" do
|
60
|
+
it "should generate an html table" do
|
61
|
+
table = subject.generate_table(objects.to_json)
|
62
|
+
doc = Nokogiri::XML(table.to_s)
|
63
|
+
doc.errors.should == []
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/spec/tag_spec.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tag do
|
4
|
+
subject{ Tag.new("table") }
|
5
|
+
|
6
|
+
describe ".new" do
|
7
|
+
it "should assign all instance variables" do
|
8
|
+
subject.instance_variable_get(:@name).should eq :table
|
9
|
+
subject.instance_variable_get(:@attributes).should eq Hash.new
|
10
|
+
subject.instance_variable_get(:@children).should eq Array.new
|
11
|
+
subject.instance_variable_get(:@text).should eq ""
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".to_s" do
|
16
|
+
it "should return tag and sub tags as string" do
|
17
|
+
subject.children << Tag.new("thead")
|
18
|
+
subject.to_s.should eq "<table><thead></thead></table>"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should insert text in between open and close tags." do
|
22
|
+
subject.text = "testing"
|
23
|
+
subject.to_s.should eq "<table>testing</table>"
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when an attribute's value is a string" do
|
27
|
+
it "should insert attributes in opening tag" do
|
28
|
+
subject.attributes = { foo: "bar" }
|
29
|
+
subject.to_s.should eq "<table foo='bar'></table>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when an attribute's value is an array" do
|
34
|
+
subject { Tag.new("tr") }
|
35
|
+
let(:attributes) { { foo: ["bar", "barz"] } }
|
36
|
+
|
37
|
+
it "should iteratively assign the corresponding value" do
|
38
|
+
tbody = Tag.new("tbody")
|
39
|
+
attributes[:foo].length.times do
|
40
|
+
tr = subject
|
41
|
+
tr.attributes = attributes
|
42
|
+
tbody.children << tr
|
43
|
+
end
|
44
|
+
|
45
|
+
attributes[:foo].each do |value|
|
46
|
+
tbody.to_s.include?("<tr foo='#{value}'>").should be_true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ".html" do
|
53
|
+
it "should return tag and sub tags as formatted string" do
|
54
|
+
subject.children << Tag.new("thead")
|
55
|
+
subject.to_html.should eq "<table>\n<thead>\n</thead>\n</table>\n"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/tablinate.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tablinate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'tablinate'
|
8
|
+
spec.date = '2016-12-02'
|
9
|
+
spec.version = Tablinate::VERSION
|
10
|
+
spec.summary = "Generate html tables with activerecord objects!"
|
11
|
+
spec.description = "Tablinate is a ruby gem that takes arrays of hashes, ActiveRecord::Relation objects, or a JSON array of hashes, and converts them into html tables. It is intended for use in small projects or applications whose schemas are closely related to what a table's output should be."
|
12
|
+
spec.authors = [ "Isabelle Carter", "Kevin Collette" ]
|
13
|
+
spec.email = [ 'isabellenataliecarter@gmail.com', 'kevcollette@gmail.com' ]
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
|
+
spec.homepage = 'http://rubygems.org/gems/tablinate'
|
17
|
+
spec.add_dependency('json')
|
18
|
+
spec.license = "MIT"
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
end
|
data/views/index.haml
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tablinate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Isabelle Carter
|
8
|
+
- Kevin Collette
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-12-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
description: Tablinate is a ruby gem that takes arrays of hashes, ActiveRecord::Relation
|
29
|
+
objects, or a JSON array of hashes, and converts them into html tables. It is intended
|
30
|
+
for use in small projects or applications whose schemas are closely related to what
|
31
|
+
a table's output should be.
|
32
|
+
email:
|
33
|
+
- isabellenataliecarter@gmail.com
|
34
|
+
- kevcollette@gmail.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- ".gitignore"
|
40
|
+
- Gemfile
|
41
|
+
- LICENSE.txt
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- lib/tablinate.rb
|
45
|
+
- lib/tablinate/adapters/active_record.rb
|
46
|
+
- lib/tablinate/adapters/array.rb
|
47
|
+
- lib/tablinate/railtie.rb
|
48
|
+
- lib/tablinate/table.rb
|
49
|
+
- lib/tablinate/table/tbody.rb
|
50
|
+
- lib/tablinate/table/thead.rb
|
51
|
+
- lib/tablinate/tag.rb
|
52
|
+
- lib/tablinate/version.rb
|
53
|
+
- spec/spec_functions.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- spec/table/tbody_spec.rb
|
56
|
+
- spec/table/thead_spec.rb
|
57
|
+
- spec/table_spec.rb
|
58
|
+
- spec/tablinate/active_record_spec.rb
|
59
|
+
- spec/tablinate/array_spec.rb
|
60
|
+
- spec/tablinate_spec.rb
|
61
|
+
- spec/tag_spec.rb
|
62
|
+
- tablinate.gemspec
|
63
|
+
- views/index.haml
|
64
|
+
homepage: http://rubygems.org/gems/tablinate
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.5.1
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Generate html tables with activerecord objects!
|
88
|
+
test_files:
|
89
|
+
- spec/spec_functions.rb
|
90
|
+
- spec/spec_helper.rb
|
91
|
+
- spec/table/tbody_spec.rb
|
92
|
+
- spec/table/thead_spec.rb
|
93
|
+
- spec/table_spec.rb
|
94
|
+
- spec/tablinate/active_record_spec.rb
|
95
|
+
- spec/tablinate/array_spec.rb
|
96
|
+
- spec/tablinate_spec.rb
|
97
|
+
- spec/tag_spec.rb
|