tabletastic 0.0.1
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.rdoc +51 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/lib/tabletastic.rb +109 -0
- data/rails/init.rb +3 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +105 -0
- data/spec/tabletastic_spec.rb +206 -0
- metadata +76 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Joshua Davey
|
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.rdoc
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
= Tabletastic
|
2
|
+
|
3
|
+
Inspired by the projects table_builder and formtastic,
|
4
|
+
I realized how often I created tables for my active record collections.
|
5
|
+
This is my attempt to simply this (the default scaffold):
|
6
|
+
|
7
|
+
<table>
|
8
|
+
<tr>
|
9
|
+
<th>Title</th>
|
10
|
+
<th>Body</th>
|
11
|
+
<th>Author Id</th>
|
12
|
+
</tr>
|
13
|
+
<% for post in @posts %>
|
14
|
+
<tr>
|
15
|
+
<td><%=h post.title %></td>
|
16
|
+
<td><%=h post.body %></td>
|
17
|
+
<td><%=h post.author_id %></td>
|
18
|
+
<td><%=h author.name %></td>
|
19
|
+
<td><%= link_to "Show", post %></td>
|
20
|
+
<td><%= link_to "Edit", edit_post_path(post) %></td>
|
21
|
+
<td><%= link_to "Destroy", post, :confirm => 'Are you sure?', :method => :delete %></td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</table>
|
25
|
+
|
26
|
+
into this:
|
27
|
+
|
28
|
+
<% table_for(@posts) do |t| %>
|
29
|
+
<%= t.data :title, :body, :author %>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
|
33
|
+
== Warning
|
34
|
+
THIS PROJECT IS UNDER HEAVY DEVELOPMENT.
|
35
|
+
IT IS NOT RECOMMENDED FOR USE IN PRODUCTION APPLICATIONS
|
36
|
+
|
37
|
+
|
38
|
+
== Note on Patches/Pull Requests
|
39
|
+
|
40
|
+
* Fork the project.
|
41
|
+
* Make your feature addition or bug fix.
|
42
|
+
* Add tests for it. This is important so I don't break it in a
|
43
|
+
future version unintentionally.
|
44
|
+
* Commit, do not mess with rakefile, version, or history.
|
45
|
+
(if you want to have your own version, that is fine but
|
46
|
+
bump version in a commit by itself I can ignore when I pull)
|
47
|
+
* Send me a pull request. Bonus points for topic branches.
|
48
|
+
|
49
|
+
== Copyright
|
50
|
+
|
51
|
+
Copyright (c) 2009 Joshua Davey. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
GEM = "tabletastic"
|
5
|
+
LONGDESCRIPTION = %Q{A table builder for active record collections \
|
6
|
+
that produces semantically rich and accessible markup}
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |s|
|
11
|
+
s.name = GEM
|
12
|
+
s.summary = %Q{A smarter table builder for Rails collections}
|
13
|
+
s.description = LONGDESCRIPTION
|
14
|
+
s.email = "josh@joshuadavey.com"
|
15
|
+
s.homepage = "http://github.com/jgdavey/tabletastic"
|
16
|
+
s.authors = ["Joshua Davey"]
|
17
|
+
s.require_path = 'lib'
|
18
|
+
|
19
|
+
s.add_development_dependency "rspec", ">= 1.2.9"
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Test the tabletastic plugin with specdoc formatting and colors'
|
34
|
+
Spec::Rake::SpecTask.new('specdoc') do |t|
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
t.spec_opts = ["--format specdoc", "-c"]
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Test the tabletastic plugin with rcov'
|
40
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
41
|
+
spec.libs << 'lib' << 'spec'
|
42
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
43
|
+
spec.rcov = true
|
44
|
+
spec.rcov_opts = ['--exclude', 'spec,Library']
|
45
|
+
end
|
46
|
+
|
47
|
+
task :spec => :check_dependencies
|
48
|
+
|
49
|
+
task :default => :spec
|
50
|
+
|
51
|
+
require 'rake/rdoctask'
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
54
|
+
|
55
|
+
rdoc.rdoc_dir = 'rdoc'
|
56
|
+
rdoc.title = "Tabletastic #{version}"
|
57
|
+
rdoc.rdoc_files.include('README*')
|
58
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/tabletastic.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module Tabletastic
|
2
|
+
|
3
|
+
def table_for(collection, *args)
|
4
|
+
options = args.extract_options!
|
5
|
+
options[:html] ||= {}
|
6
|
+
options[:html][:id] ||= get_id_for(collection)
|
7
|
+
concat(tag(:table, options[:html], true))
|
8
|
+
yield TableBuilder.new(collection, self)
|
9
|
+
concat("</table>")
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_id_for(collection)
|
13
|
+
!collection.empty? && collection.first.class.to_s.tableize
|
14
|
+
end
|
15
|
+
|
16
|
+
class TableBuilder
|
17
|
+
@@association_methods = %w[to_label display_name full_name name title username login value to_s]
|
18
|
+
|
19
|
+
def initialize(collection, template)
|
20
|
+
@collection, @template = collection, template
|
21
|
+
end
|
22
|
+
|
23
|
+
def data(*args, &block)
|
24
|
+
if block_given?
|
25
|
+
yield self
|
26
|
+
@template.concat(headers)
|
27
|
+
@template.concat(body)
|
28
|
+
else
|
29
|
+
@fields = args unless args.empty?
|
30
|
+
headers + body
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def headers
|
35
|
+
content_tag(:thead) do
|
36
|
+
header_row
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def header_row
|
41
|
+
output = "<tr>"
|
42
|
+
fields.each do |field|
|
43
|
+
output += content_tag(:th, field.to_s.humanize)
|
44
|
+
end
|
45
|
+
output += "</tr>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def body
|
49
|
+
content_tag(:tbody) do
|
50
|
+
body_rows
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def body_rows
|
55
|
+
@collection.inject("") do |rows, record|
|
56
|
+
rowclass = @template.cycle("odd","even")
|
57
|
+
rows += @template.content_tag_for(:tr, record, :class => rowclass) do
|
58
|
+
tds_for_row(record)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def tds_for_row(record)
|
64
|
+
fields.inject("") do |cells, field|
|
65
|
+
cells += content_tag(:td, cell_for(record, field))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def cell_for(record, method_or_attribute)
|
70
|
+
result = record.send(method_or_attribute)
|
71
|
+
return result if result.is_a?(String)
|
72
|
+
to_string = detect_string_method(result)
|
73
|
+
result.send(to_string) if to_string
|
74
|
+
end
|
75
|
+
|
76
|
+
def detect_string_method(association)
|
77
|
+
@@association_methods.detect { |method| association.respond_to?(method) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def cell(method_or_attribute)
|
81
|
+
@fields ||= []
|
82
|
+
@fields << method_or_attribute.to_sym
|
83
|
+
return ""
|
84
|
+
end
|
85
|
+
|
86
|
+
def fields
|
87
|
+
return @fields if defined?(@fields)
|
88
|
+
if @collection.empty?
|
89
|
+
@fields = []
|
90
|
+
else
|
91
|
+
object = @collection.first
|
92
|
+
associations = object.class.reflect_on_all_associations(:belongs_to) if object.class.respond_to?(:reflect_on_all_associations)
|
93
|
+
@fields = object.class.content_columns.map(&:name)
|
94
|
+
if associations
|
95
|
+
associations = associations.map(&:name)
|
96
|
+
@fields += associations
|
97
|
+
end
|
98
|
+
@fields -= %w[created_at updated_at created_on updated_on lock_version version]
|
99
|
+
@fields.map!(&:to_sym)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def content_tag(name, content = nil, options = nil, escape = true, &block)
|
106
|
+
@template.content_tag(name, content, options, escape, &block)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/rails/init.rb
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
def smart_require(lib_name, gem_name, gem_version = '>= 0.0.0')
|
5
|
+
begin
|
6
|
+
require lib_name if lib_name
|
7
|
+
rescue LoadError
|
8
|
+
if gem_name
|
9
|
+
gem gem_name, gem_version
|
10
|
+
require lib_name if lib_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
smart_require 'spec', 'spec', '>= 1.2.8'
|
16
|
+
require 'spec/autorun'
|
17
|
+
smart_require false, 'rspec-rails', '>= 1.2.7.1'
|
18
|
+
smart_require 'hpricot', 'hpricot', '>= 0.6.1'
|
19
|
+
smart_require 'rspec_hpricot_matchers', 'rspec_hpricot_matchers', '>= 1.0.0'
|
20
|
+
smart_require 'active_support', 'activesupport', '>= 2.3.4'
|
21
|
+
smart_require 'action_controller', 'actionpack', '>= 2.3.4'
|
22
|
+
smart_require 'action_view', 'actionpack', '>= 2.3.4'
|
23
|
+
|
24
|
+
Spec::Runner.configure do |config|
|
25
|
+
config.include(RspecHpricotMatchers)
|
26
|
+
end
|
27
|
+
|
28
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
29
|
+
require 'tabletastic'
|
30
|
+
|
31
|
+
module TabletasticSpecHelper
|
32
|
+
include ActionView::Helpers::UrlHelper
|
33
|
+
include ActionView::Helpers::TagHelper
|
34
|
+
include ActionView::Helpers::TextHelper
|
35
|
+
include ActionView::Helpers::ActiveRecordHelper
|
36
|
+
include ActionView::Helpers::RecordIdentificationHelper
|
37
|
+
include ActionView::Helpers::RecordTagHelper
|
38
|
+
include ActionView::Helpers::CaptureHelper
|
39
|
+
include ActiveSupport
|
40
|
+
include ActionController::PolymorphicRoutes
|
41
|
+
|
42
|
+
def self.included(base)
|
43
|
+
base.class_eval do
|
44
|
+
attr_accessor :output_buffer
|
45
|
+
def protect_against_forgery?
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module ::RspecHpricotMatchers
|
52
|
+
def have_table_with_tag(selector, inner_text_or_options = nil, options = {}, &block)
|
53
|
+
HaveTag.new("table", nil, {}) &&
|
54
|
+
HaveTag.new(selector, inner_text_or_options, options, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class ::Post
|
59
|
+
def id
|
60
|
+
end
|
61
|
+
end
|
62
|
+
class ::Author
|
63
|
+
end
|
64
|
+
|
65
|
+
def mock_everything
|
66
|
+
def post_path(post); "/posts/#{post.id}"; end
|
67
|
+
def edit_post_path(post); "/posts/#{post.id}/edit"; end
|
68
|
+
|
69
|
+
# Sometimes we need a mock @post object and some Authors for belongs_to
|
70
|
+
@post = mock('post')
|
71
|
+
@post.stub!(:class).and_return(::Post)
|
72
|
+
@post.stub!(:id).and_return(nil)
|
73
|
+
@post.stub!(:author)
|
74
|
+
::Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
|
75
|
+
::Post.stub!(:human_name).and_return('Post')
|
76
|
+
|
77
|
+
@fred = mock('user')
|
78
|
+
@fred.stub!(:class).and_return(::Author)
|
79
|
+
@fred.stub!(:name).and_return('Fred Smith')
|
80
|
+
@fred.stub!(:id).and_return(37)
|
81
|
+
|
82
|
+
::Author.stub!(:find).and_return([@fred])
|
83
|
+
::Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
|
84
|
+
::Author.stub!(:human_name).and_return('Author')
|
85
|
+
::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
|
86
|
+
|
87
|
+
@freds_post = mock('post')
|
88
|
+
@freds_post.stub!(:class).and_return(::Post)
|
89
|
+
@freds_post.stub!(:title).and_return('Fred\'s Post')
|
90
|
+
@freds_post.stub!(:body)
|
91
|
+
@freds_post.stub!(:id).and_return(19)
|
92
|
+
@freds_post.stub!(:author).and_return(@fred)
|
93
|
+
@freds_post.stub!(:author_id).and_return(@fred.id)
|
94
|
+
@fred.stub!(:posts).and_return([@freds_post])
|
95
|
+
@fred.stub!(:post_ids).and_return([@freds_post.id])
|
96
|
+
|
97
|
+
@mock_reflection_belongs_to_author = mock('reflection', :options => {}, :name => :author, :klass => ::Author, :macro => :belongs_to)
|
98
|
+
|
99
|
+
::Post.stub!(:reflect_on_association).and_return do |column_name|
|
100
|
+
@mock_reflection_belongs_to_author if column_name == :author
|
101
|
+
end
|
102
|
+
|
103
|
+
::Post.stub!(:reflect_on_all_associations).with(:belongs_to).and_return([])
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
include TabletasticSpecHelper
|
3
|
+
include Tabletastic
|
4
|
+
|
5
|
+
|
6
|
+
describe "Tabletastic#table_for" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@output_buffer = ''
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "basics" do
|
13
|
+
it "should start with an empty output buffer" do
|
14
|
+
output_buffer.should_not have_tag("table")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should build a basic table" do
|
18
|
+
table_for([]) do |t|
|
19
|
+
end
|
20
|
+
output_buffer.should have_tag("table")
|
21
|
+
end
|
22
|
+
|
23
|
+
context "headers and table body" do
|
24
|
+
before do
|
25
|
+
table_for([]) do |t|
|
26
|
+
concat(t.headers)
|
27
|
+
concat(t.body)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should build a basic table and headers" do
|
32
|
+
output_buffer.should have_table_with_tag("thead")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should build a basic table and body" do
|
36
|
+
output_buffer.should have_table_with_tag("tbody")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with options" do
|
41
|
+
it "should pass along html options" do
|
42
|
+
table_for([], :html => {:class => 'special'}) do |t|
|
43
|
+
end
|
44
|
+
output_buffer.should have_tag("table.special")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#data" do
|
50
|
+
before do
|
51
|
+
mock_everything
|
52
|
+
::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
|
53
|
+
@post.stub!(:title).and_return("The title of the post")
|
54
|
+
@post.stub!(:body).and_return("Lorem ipsum")
|
55
|
+
@post.stub!(:created_at).and_return(Time.now)
|
56
|
+
@post.stub!(:id).and_return(2)
|
57
|
+
@posts = [@post]
|
58
|
+
end
|
59
|
+
|
60
|
+
context "without a block" do
|
61
|
+
context "with no other arguments" do
|
62
|
+
before do
|
63
|
+
table_for(@posts) do |t|
|
64
|
+
concat(t.data)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should output table with id of the class of the collection" do
|
69
|
+
output_buffer.should have_tag("table#posts")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should output headers" do
|
73
|
+
output_buffer.should have_table_with_tag("thead")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should have a <th> for each attribute" do
|
77
|
+
# title and body
|
78
|
+
output_buffer.should have_table_with_tag("th", :count => 2)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should include header for Title" do
|
82
|
+
output_buffer.should have_table_with_tag("th", "Title")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should include header for Body" do
|
86
|
+
output_buffer.should have_table_with_tag("th", "Body")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should output body" do
|
90
|
+
output_buffer.should have_table_with_tag("tbody")
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should include a row for each record" do
|
94
|
+
output_buffer.should have_table_with_tag("tbody") do |tbody|
|
95
|
+
tbody.should have_tag("tr", :count => 1)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have data for each field" do
|
100
|
+
output_buffer.should have_table_with_tag("td", "The title of the post")
|
101
|
+
output_buffer.should have_table_with_tag("td", "Lorem ipsum")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should include the id for the <tr> for each record" do
|
105
|
+
output_buffer.should have_table_with_tag("tr#post_#{@post.id}")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should cycle row classes" do
|
109
|
+
@output_buffer = ""
|
110
|
+
@posts = [@post, @post]
|
111
|
+
table_for(@posts) do |t|
|
112
|
+
concat(t.data)
|
113
|
+
end
|
114
|
+
output_buffer.should have_table_with_tag("tr.odd")
|
115
|
+
output_buffer.should have_table_with_tag("tr.even")
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when collection has associations" do
|
119
|
+
it "should handle belongs_to associations" do
|
120
|
+
::Post.stub!(:reflect_on_all_associations).with(:belongs_to).and_return([@mock_reflection_belongs_to_author])
|
121
|
+
@posts = [@freds_post]
|
122
|
+
@output_buffer = ""
|
123
|
+
table_for(@posts) do |t|
|
124
|
+
concat(t.data)
|
125
|
+
end
|
126
|
+
output_buffer.should have_table_with_tag("th", "Author")
|
127
|
+
output_buffer.should have_table_with_tag("td", "Fred Smith")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "with a list of attributes" do
|
133
|
+
before do
|
134
|
+
table_for(@posts) do |t|
|
135
|
+
concat(t.data(:title, :created_at))
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should call each method passed in, and only those methods" do
|
140
|
+
output_buffer.should have_table_with_tag("th", "Title")
|
141
|
+
output_buffer.should have_table_with_tag("th", "Created at")
|
142
|
+
output_buffer.should_not have_table_with_tag("th", "Body")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with a block" do
|
148
|
+
context "and normal columns" do
|
149
|
+
before do
|
150
|
+
table_for(@posts) do |t|
|
151
|
+
t.data do
|
152
|
+
concat(t.cell(:title))
|
153
|
+
concat(t.cell(:body))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should include the data for the fields passed in" do
|
159
|
+
output_buffer.should have_table_with_tag("th", "Title")
|
160
|
+
output_buffer.should have_tag("td", "The title of the post")
|
161
|
+
output_buffer.should have_tag("td", "Lorem ipsum")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "and normal/association columns" do
|
166
|
+
before do
|
167
|
+
::Post.stub!(:reflect_on_all_associations).with(:belongs_to).and_return([@mock_reflection_belongs_to_author])
|
168
|
+
@posts = [@freds_post]
|
169
|
+
table_for(@posts) do |t|
|
170
|
+
t.data do
|
171
|
+
concat(t.cell(:title))
|
172
|
+
concat(t.cell(:author))
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should include normal columns" do
|
178
|
+
output_buffer.should have_table_with_tag("th:nth-child(1)", "Title")
|
179
|
+
output_buffer.should have_table_with_tag("td:nth-child(1)", "Fred's Post")
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should include belongs_to associations" do
|
183
|
+
output_buffer.should have_table_with_tag("th:nth-child(2)", "Author")
|
184
|
+
output_buffer.should have_table_with_tag("td:nth-child(2)", "Fred Smith")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe TableBuilder do
|
192
|
+
before do
|
193
|
+
mock_everything
|
194
|
+
::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
|
195
|
+
@posts = [@post, Post.new]
|
196
|
+
@builder = TableBuilder.new(@posts, nil)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should detect attributes" do
|
200
|
+
@builder.fields.should include(:title)
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should reject marked attributes" do
|
204
|
+
@builder.fields.should_not include(:created_at)
|
205
|
+
end
|
206
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tabletastic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Davey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-15 00:00:00 -06: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
|
+
description: A table builder for active record collections that produces semantically rich and accessible markup
|
26
|
+
email: josh@joshuadavey.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- lib/tabletastic.rb
|
42
|
+
- rails/init.rb
|
43
|
+
- spec/spec.opts
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
- spec/tabletastic_spec.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/jgdavey/tabletastic
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: A smarter table builder for Rails collections
|
74
|
+
test_files:
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
- spec/tabletastic_spec.rb
|