totally_tabular 0.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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.textile +79 -0
- data/Rakefile +70 -0
- data/VERSION +1 -0
- data/lib/core_ext/object.rb +8 -0
- data/lib/core_ext/proc.rb +13 -0
- data/lib/totally_tabular/column.rb +30 -0
- data/lib/totally_tabular/html_helper.rb +21 -0
- data/lib/totally_tabular/row.rb +19 -0
- data/lib/totally_tabular/table.rb +18 -0
- data/lib/totally_tabular/table_view.rb +57 -0
- data/lib/totally_tabular.rb +3 -0
- data/spec/lib/core_ext/instance_exec_spec.rb +16 -0
- data/spec/lib/totally_tabular/html_helper_spec.rb +48 -0
- data/spec/lib/totally_tabular/table_view_spec.rb +180 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/totally_tabular_spec.rb +7 -0
- data/totally_tabular.gemspec +71 -0
- metadata +99 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 Joe Fiorini
|
|
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
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
h1. Totally Tabular!
|
|
2
|
+
|
|
3
|
+
Assuming I have 5 people with:
|
|
4
|
+
|
|
5
|
+
* first_name
|
|
6
|
+
* last_name
|
|
7
|
+
* registration_status
|
|
8
|
+
|
|
9
|
+
My pointy-haired boss wants to see a list of these people on our
|
|
10
|
+
administrative dashboard. Sure, I could write some ugly ERB like so:
|
|
11
|
+
|
|
12
|
+
<pre>
|
|
13
|
+
<code>
|
|
14
|
+
<table class="people">
|
|
15
|
+
<thead>
|
|
16
|
+
<tr>
|
|
17
|
+
<th class="header">First Name</th>
|
|
18
|
+
<th>Last Name</th>
|
|
19
|
+
<th>Registration Status</th>
|
|
20
|
+
</tr>
|
|
21
|
+
</thead>
|
|
22
|
+
<tbody>
|
|
23
|
+
<% @people.each do |person| %>
|
|
24
|
+
<tr class="<%= person.registration_status %>">
|
|
25
|
+
<td>Michael Bluth</td>
|
|
26
|
+
<td>Bluth</td>
|
|
27
|
+
<td>
|
|
28
|
+
<% if person.registered? %>
|
|
29
|
+
<strong>Registered</strong>
|
|
30
|
+
<% else %>
|
|
31
|
+
<em>Unregistered</em>
|
|
32
|
+
<% end %>
|
|
33
|
+
</tr>
|
|
34
|
+
<% end %>
|
|
35
|
+
</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
</code>
|
|
38
|
+
</pre>
|
|
39
|
+
|
|
40
|
+
But why? I mean, we're using Ruby for Pete's sake! How about a cleaner way to do the same thing?
|
|
41
|
+
|
|
42
|
+
<pre>
|
|
43
|
+
<code>
|
|
44
|
+
<%= person_table(people_presenter.people, :class => 'people') %>
|
|
45
|
+
</code>
|
|
46
|
+
</pre>
|
|
47
|
+
|
|
48
|
+
Okay, so that's just a custom Rails helper method. Nothing special. But let's look at the definition of the helper method! That's where the special sauce is.
|
|
49
|
+
|
|
50
|
+
<pre>
|
|
51
|
+
<code>
|
|
52
|
+
def person_table(people, attributes={})
|
|
53
|
+
TableView.new(@people, :class => 'people') do
|
|
54
|
+
define_column("First Name") do |person|
|
|
55
|
+
header_attributes!(:class => 'header')
|
|
56
|
+
row_attributes!(:class => person.registration_status)
|
|
57
|
+
template! do
|
|
58
|
+
person.first_name
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
define_column("Last Name") do |person|
|
|
62
|
+
template! do
|
|
63
|
+
person.last_name
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
define_column("Registration Status") do |person|
|
|
67
|
+
template! do
|
|
68
|
+
if person.registered?
|
|
69
|
+
content_tag(:strong, "Registered")
|
|
70
|
+
else
|
|
71
|
+
content_tag(:em, "Unregistered")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
</code>
|
|
78
|
+
</pre>
|
|
79
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "totally_tabular"
|
|
8
|
+
gem.summary = %Q{DSL for creating HTML tables}
|
|
9
|
+
gem.description = %Q{HTML tables are a pain in the ass. Use totaly_tabular to help make creating tables a breeze!}
|
|
10
|
+
gem.email = "joe@joefiorini.com"
|
|
11
|
+
gem.homepage = "http://github.com/faithfulgeek/totally_tabular"
|
|
12
|
+
gem.authors = ["Joe Fiorini"]
|
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
|
14
|
+
gem.add_development_dependency "yard", ">= 0"
|
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
16
|
+
end
|
|
17
|
+
Jeweler::GemcutterTasks.new
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'spec/rake/spectask'
|
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
31
|
+
spec.rcov = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
task :spec => :check_dependencies
|
|
35
|
+
|
|
36
|
+
begin
|
|
37
|
+
require 'reek/adapters/rake_task'
|
|
38
|
+
Reek::RakeTask.new do |t|
|
|
39
|
+
t.fail_on_error = true
|
|
40
|
+
t.verbose = false
|
|
41
|
+
t.source_files = 'lib/**/*.rb'
|
|
42
|
+
end
|
|
43
|
+
rescue LoadError
|
|
44
|
+
task :reek do
|
|
45
|
+
abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
require 'roodi'
|
|
51
|
+
require 'roodi_task'
|
|
52
|
+
RoodiTask.new do |t|
|
|
53
|
+
t.verbose = false
|
|
54
|
+
end
|
|
55
|
+
rescue LoadError
|
|
56
|
+
task :roodi do
|
|
57
|
+
abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
task :default => :spec
|
|
62
|
+
|
|
63
|
+
begin
|
|
64
|
+
require 'yard'
|
|
65
|
+
YARD::Rake::YardocTask.new
|
|
66
|
+
rescue LoadError
|
|
67
|
+
task :yardoc do
|
|
68
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
|
69
|
+
end
|
|
70
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Proc #:nodoc:
|
|
2
|
+
def bind(object)
|
|
3
|
+
block, time = self, Time.now
|
|
4
|
+
(class << object; self end).class_eval do
|
|
5
|
+
method_name = "__bind_#{time.to_i}_#{time.usec}"
|
|
6
|
+
define_method(method_name, &block)
|
|
7
|
+
method = instance_method(method_name)
|
|
8
|
+
remove_method(method_name)
|
|
9
|
+
method
|
|
10
|
+
end.bind(object)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module TotallyTabular
|
|
2
|
+
class Column
|
|
3
|
+
attr_accessor :name, :template, :header_attributes, :row_attributes, :definition, :cell_attributes
|
|
4
|
+
|
|
5
|
+
def initialize(name, &block)
|
|
6
|
+
@name = name
|
|
7
|
+
@header_attributes = {}
|
|
8
|
+
@row_attributes = {}
|
|
9
|
+
@cell_attributes = {}
|
|
10
|
+
@definition = block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def template!(&block)
|
|
14
|
+
@template = block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def header_attributes!(attributes={})
|
|
18
|
+
@header_attributes = attributes
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def row_attributes!(attributes={})
|
|
22
|
+
@row_attributes = attributes
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cell_attributes!(attributes={})
|
|
26
|
+
@cell_attributes = attributes
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module TotallyTabular
|
|
2
|
+
class HtmlHelper
|
|
3
|
+
|
|
4
|
+
EMPTY_TAG = /br|hr|img|meta|link|input|base|area|col|frame|param/
|
|
5
|
+
|
|
6
|
+
def content_tag(tag, content="", attributes={})
|
|
7
|
+
if tag.to_s =~ EMPTY_TAG
|
|
8
|
+
"<%s%s>" % [tag, attrs(attributes)]
|
|
9
|
+
else
|
|
10
|
+
"<%s%s>%s</%s>" % [tag, attrs(attributes), content, tag]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def attrs(attributes)
|
|
17
|
+
return "" if attributes.empty?
|
|
18
|
+
attr_string = ' %s' % attributes.map { |attr| '%s="%s"' % attr }.join(" ")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module TotallyTabular
|
|
2
|
+
class Row
|
|
3
|
+
|
|
4
|
+
def initialize
|
|
5
|
+
@helper = HtmlHelper.new
|
|
6
|
+
@attributes = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def attributes!(attributes={})
|
|
10
|
+
@attributes = attributes
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def render(content)
|
|
14
|
+
if !content.empty?
|
|
15
|
+
@helper.content_tag(:tr, content, @attributes)
|
|
16
|
+
end.to_s
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module TotallyTabular
|
|
2
|
+
class Table
|
|
3
|
+
attr_reader :columns
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@columns = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def define_column(name, header_attributes={}, &block)
|
|
10
|
+
column = Column.new(name, &block)
|
|
11
|
+
@columns << column
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def columns_count
|
|
15
|
+
@columns.length
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/table'
|
|
2
|
+
require File.dirname(__FILE__) + '/column'
|
|
3
|
+
require File.dirname(__FILE__) + '/row'
|
|
4
|
+
require File.dirname(__FILE__) + '/html_helper'
|
|
5
|
+
|
|
6
|
+
module TotallyTabular
|
|
7
|
+
class TableView
|
|
8
|
+
|
|
9
|
+
def initialize(collection, options={}, &block)
|
|
10
|
+
@collection = collection
|
|
11
|
+
@options = options
|
|
12
|
+
@column_definition = block
|
|
13
|
+
@helper = HtmlHelper.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render
|
|
17
|
+
table = Table.new
|
|
18
|
+
table.instance_eval(&@column_definition)
|
|
19
|
+
rows = build_rows(@collection, table.columns)
|
|
20
|
+
headers = if @collection.empty?
|
|
21
|
+
""
|
|
22
|
+
else
|
|
23
|
+
build_headers(table.columns)
|
|
24
|
+
end
|
|
25
|
+
tbody = @helper.content_tag(:tbody, rows.join)
|
|
26
|
+
thead = @helper.content_tag(:thead, headers)
|
|
27
|
+
tfoot = @helper.content_tag(:tfoot)
|
|
28
|
+
@helper.content_tag(:table, [thead, tbody, tfoot], options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def options
|
|
32
|
+
@options
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def build_rows(collection, columns)
|
|
38
|
+
collection.map do |item|
|
|
39
|
+
row = Row.new
|
|
40
|
+
row_attributes = nil
|
|
41
|
+
row.render(columns.map do |column|
|
|
42
|
+
column.instance_exec(item, &column.definition)
|
|
43
|
+
row.attributes!(column.row_attributes)
|
|
44
|
+
@helper.content_tag(:td, column.template.call(item, row), column.cell_attributes)
|
|
45
|
+
end.join)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def build_headers(columns)
|
|
50
|
+
headers = columns.map do |column|
|
|
51
|
+
@helper.content_tag(:th, column.name, column.header_attributes)
|
|
52
|
+
end
|
|
53
|
+
Row.new.render(headers)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "instance_exec" do
|
|
4
|
+
|
|
5
|
+
it "should have instance_exec method on object" do
|
|
6
|
+
Object.new.should respond_to(:instance_exec)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should provide arguments in a block" do
|
|
10
|
+
the_object = Object.new
|
|
11
|
+
final_object = nil
|
|
12
|
+
b = Proc.new { |o| final_object = o }
|
|
13
|
+
Object.new.instance_exec(the_object, &b)
|
|
14
|
+
final_object.should == the_object
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
include TotallyTabular
|
|
4
|
+
|
|
5
|
+
describe HtmlHelper do
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
@helper = HtmlHelper.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "is instantiated" do
|
|
12
|
+
@helper.should_not be_nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "returns an empty table tag" do
|
|
16
|
+
@helper.content_tag(:table).should == "<table></table>"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "returns an empty br tag" do
|
|
20
|
+
@helper.content_tag(:br).should == "<br>"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "returns an empty input tag" do
|
|
24
|
+
@helper.content_tag(:input).should == "<input>"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns an empty img tag" do
|
|
28
|
+
@helper.content_tag(:img).should == "<img>"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "returns a tag with content" do
|
|
32
|
+
@helper.content_tag(:strong, "blah").should == "<strong>blah</strong>"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "renders with a class specified" do
|
|
36
|
+
@helper.content_tag(:strong, "blah", :class => "diddy").should =~ /class=\"diddy\"/
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "renders with a href attribute specified" do
|
|
40
|
+
url = "http://www.google.com"
|
|
41
|
+
@helper.content_tag(:a, "blah", :href => url).should =~ /href=\"#{url}\"/
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "renders empty tags with attributes" do
|
|
45
|
+
src = "http://www.asite.com/images/my_image.jpg"
|
|
46
|
+
@helper.content_tag(:img, "", :src => src).should =~ /src=\"#{src}\"/
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
require 'nokogiri'
|
|
5
|
+
|
|
6
|
+
include TotallyTabular
|
|
7
|
+
|
|
8
|
+
describe TableView do
|
|
9
|
+
|
|
10
|
+
def selector(string, selector)
|
|
11
|
+
Nokogiri(string).css(selector)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before do
|
|
15
|
+
@table_view = TableView.new([]) do
|
|
16
|
+
define_column("col") do |o|
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should be instantiated" do
|
|
22
|
+
@table_view.should_not be_nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should take a collection when initialized" do
|
|
26
|
+
lambda { TableView.new }.should raise_error(ArgumentError)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should take a hash of options" do
|
|
30
|
+
lambda { TableView.new(mock, {}) }.should_not raise_error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should render an empty table" do
|
|
34
|
+
@table_view.render.should == "<table><thead></thead><tbody></tbody><tfoot></tfoot></table>"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should render with a class" do
|
|
38
|
+
table_class = "CLASS"
|
|
39
|
+
|
|
40
|
+
t = TableView.new([], :class => table_class) do |table|
|
|
41
|
+
table.define_column("col") do |o|
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
selector(t.render, "table.#{table_class}").should_not be_empty
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should render with cellpadding, cellspacing" do
|
|
49
|
+
t = TableView.new([], :cellpadding => 0, :cellspacing => 0) do |table|
|
|
50
|
+
table.define_column("col") do |o|
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
selector(t.render, "table[cellpadding='0']").should_not be_empty
|
|
55
|
+
selector(t.render, "table[cellspacing='0']").should_not be_empty
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "displaying multiple objects in rows" do
|
|
59
|
+
|
|
60
|
+
before do
|
|
61
|
+
o = OpenStruct.new(:name => "Joe", :coolness => "Really cool!", :age => 28)
|
|
62
|
+
o2 = OpenStruct.new(:name => "Jonathan", :coolness => "Kinda cool.", :age => 33)
|
|
63
|
+
o3 = OpenStruct.new(:name => "Gary", :coolness => "Eh.", :age => 26)
|
|
64
|
+
o4 = OpenStruct.new(:name => "Josh", :coolness => "Lame.", :age => 26)
|
|
65
|
+
@table_view = TableView.new([o, o2, o3, o4]) do |t|
|
|
66
|
+
t.define_column("Name") do |o|
|
|
67
|
+
template! do
|
|
68
|
+
"%s is %s" % [o.name, o.coolness]
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
t.define_column("Age") do |o|
|
|
72
|
+
template! do
|
|
73
|
+
o.age
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
@result = @table_view.render
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should display 4 rows" do
|
|
81
|
+
selector(@result, "table tbody tr").length.should == 4
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should have 2 column headers" do
|
|
85
|
+
selector(@result, "table thead th").length.should == 2
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should have 2 columns" do
|
|
89
|
+
selector(@result, "table tr:first-child td").length.should == 2
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context "defining columns" do
|
|
94
|
+
|
|
95
|
+
it "allows defining class on header" do
|
|
96
|
+
t = TableView.new([1]) do
|
|
97
|
+
define_column("Blah") do |o|
|
|
98
|
+
header_attributes!(:class => 'blahdiddy')
|
|
99
|
+
template! do
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
selector(t.render, "table th.blahdiddy").length.should == 1
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "allows defining a class on row" do
|
|
108
|
+
t = TableView.new([1]) do
|
|
109
|
+
define_column("Blah") do |o|
|
|
110
|
+
row_attributes!(:class => 'diddy')
|
|
111
|
+
template! do
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
selector(t.render, "table tr.diddy").length.should == 1
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "allows defining a class from an object attribute" do
|
|
120
|
+
obj = OpenStruct.new(:status => 'unread')
|
|
121
|
+
t = TableView.new([obj]) do
|
|
122
|
+
define_column("Blah") do |o|
|
|
123
|
+
row_attributes!(:class => o.status)
|
|
124
|
+
template! do
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
selector(t.render, "table tr.unread").length.should == 1
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "allows defining a class on the cell" do
|
|
133
|
+
t = TableView.new([1]) do
|
|
134
|
+
define_column("Blah") do |o|
|
|
135
|
+
cell_attributes!(:class => 'diddy')
|
|
136
|
+
template! {}
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
selector(t.render, "table td.diddy").length.should == 1
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should take a block and give a table class" do
|
|
144
|
+
table = TableView::Table.new
|
|
145
|
+
TableView::Table.stub!(:new).and_return(table)
|
|
146
|
+
|
|
147
|
+
column_definition = Proc.new { }
|
|
148
|
+
table_view = TableView.new([], {}, &column_definition)
|
|
149
|
+
|
|
150
|
+
table.should_receive(:instance_eval)
|
|
151
|
+
|
|
152
|
+
table_view.render
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "should allow me to define a column" do
|
|
156
|
+
column_definition = Proc.new do
|
|
157
|
+
define_column("Joe") do
|
|
158
|
+
template! do
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
t = TableView.new([], {}, &column_definition)
|
|
164
|
+
lambda { t.render }.should_not raise_error
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "should allow defining the column body when defining the column" do
|
|
168
|
+
t = TableView.new(["Judge"]) do
|
|
169
|
+
define_column("Name") do |item|
|
|
170
|
+
template! do
|
|
171
|
+
"My name is %s." % item
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
selector(t.render, "table tr td").inner_html.should == "My name is Judge."
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
end
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{totally_tabular}
|
|
8
|
+
s.version = "0.1.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Joe Fiorini"]
|
|
12
|
+
s.date = %q{2010-01-17}
|
|
13
|
+
s.description = %q{HTML tables are a pain in the ass. Use totaly_tabular to help make creating tables a breeze!}
|
|
14
|
+
s.email = %q{joe@joefiorini.com}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.textile"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".document",
|
|
21
|
+
".gitignore",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"README.textile",
|
|
24
|
+
"Rakefile",
|
|
25
|
+
"VERSION",
|
|
26
|
+
"lib/core_ext/object.rb",
|
|
27
|
+
"lib/core_ext/proc.rb",
|
|
28
|
+
"lib/totally_tabular.rb",
|
|
29
|
+
"lib/totally_tabular/column.rb",
|
|
30
|
+
"lib/totally_tabular/html_helper.rb",
|
|
31
|
+
"lib/totally_tabular/row.rb",
|
|
32
|
+
"lib/totally_tabular/table.rb",
|
|
33
|
+
"lib/totally_tabular/table_view.rb",
|
|
34
|
+
"spec/lib/core_ext/instance_exec_spec.rb",
|
|
35
|
+
"spec/lib/totally_tabular/html_helper_spec.rb",
|
|
36
|
+
"spec/lib/totally_tabular/table_view_spec.rb",
|
|
37
|
+
"spec/spec.opts",
|
|
38
|
+
"spec/spec_helper.rb",
|
|
39
|
+
"spec/totally_tabular_spec.rb",
|
|
40
|
+
"totally_tabular.gemspec"
|
|
41
|
+
]
|
|
42
|
+
s.homepage = %q{http://github.com/faithfulgeek/totally_tabular}
|
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
44
|
+
s.require_paths = ["lib"]
|
|
45
|
+
s.rubygems_version = %q{1.3.5}
|
|
46
|
+
s.summary = %q{DSL for creating HTML tables}
|
|
47
|
+
s.test_files = [
|
|
48
|
+
"spec/lib/core_ext/instance_exec_spec.rb",
|
|
49
|
+
"spec/lib/totally_tabular/html_helper_spec.rb",
|
|
50
|
+
"spec/lib/totally_tabular/table_view_spec.rb",
|
|
51
|
+
"spec/spec_helper.rb",
|
|
52
|
+
"spec/totally_tabular_spec.rb"
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
if s.respond_to? :specification_version then
|
|
56
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
57
|
+
s.specification_version = 3
|
|
58
|
+
|
|
59
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
60
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
|
61
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
|
62
|
+
else
|
|
63
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
|
64
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
|
68
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
metadata
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: totally_tabular
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Joe Fiorini
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2010-01-17 00:00:00 -05:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: rspec
|
|
17
|
+
type: :development
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 1.2.9
|
|
24
|
+
version:
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: yard
|
|
27
|
+
type: :development
|
|
28
|
+
version_requirement:
|
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: "0"
|
|
34
|
+
version:
|
|
35
|
+
description: HTML tables are a pain in the ass. Use totaly_tabular to help make creating tables a breeze!
|
|
36
|
+
email: joe@joefiorini.com
|
|
37
|
+
executables: []
|
|
38
|
+
|
|
39
|
+
extensions: []
|
|
40
|
+
|
|
41
|
+
extra_rdoc_files:
|
|
42
|
+
- LICENSE
|
|
43
|
+
- README.textile
|
|
44
|
+
files:
|
|
45
|
+
- .document
|
|
46
|
+
- .gitignore
|
|
47
|
+
- LICENSE
|
|
48
|
+
- README.textile
|
|
49
|
+
- Rakefile
|
|
50
|
+
- VERSION
|
|
51
|
+
- lib/core_ext/object.rb
|
|
52
|
+
- lib/core_ext/proc.rb
|
|
53
|
+
- lib/totally_tabular.rb
|
|
54
|
+
- lib/totally_tabular/column.rb
|
|
55
|
+
- lib/totally_tabular/html_helper.rb
|
|
56
|
+
- lib/totally_tabular/row.rb
|
|
57
|
+
- lib/totally_tabular/table.rb
|
|
58
|
+
- lib/totally_tabular/table_view.rb
|
|
59
|
+
- spec/lib/core_ext/instance_exec_spec.rb
|
|
60
|
+
- spec/lib/totally_tabular/html_helper_spec.rb
|
|
61
|
+
- spec/lib/totally_tabular/table_view_spec.rb
|
|
62
|
+
- spec/spec.opts
|
|
63
|
+
- spec/spec_helper.rb
|
|
64
|
+
- spec/totally_tabular_spec.rb
|
|
65
|
+
- totally_tabular.gemspec
|
|
66
|
+
has_rdoc: true
|
|
67
|
+
homepage: http://github.com/faithfulgeek/totally_tabular
|
|
68
|
+
licenses: []
|
|
69
|
+
|
|
70
|
+
post_install_message:
|
|
71
|
+
rdoc_options:
|
|
72
|
+
- --charset=UTF-8
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: "0"
|
|
80
|
+
version:
|
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: "0"
|
|
86
|
+
version:
|
|
87
|
+
requirements: []
|
|
88
|
+
|
|
89
|
+
rubyforge_project:
|
|
90
|
+
rubygems_version: 1.3.5
|
|
91
|
+
signing_key:
|
|
92
|
+
specification_version: 3
|
|
93
|
+
summary: DSL for creating HTML tables
|
|
94
|
+
test_files:
|
|
95
|
+
- spec/lib/core_ext/instance_exec_spec.rb
|
|
96
|
+
- spec/lib/totally_tabular/html_helper_spec.rb
|
|
97
|
+
- spec/lib/totally_tabular/table_view_spec.rb
|
|
98
|
+
- spec/spec_helper.rb
|
|
99
|
+
- spec/totally_tabular_spec.rb
|