datagrid 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,91 +1,105 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- abstract (1.0.0)
5
4
  accept_values_for (0.4.3)
6
5
  activemodel (>= 3.0.0)
7
6
  rspec
8
- actionmailer (3.0.7)
9
- actionpack (= 3.0.7)
10
- mail (~> 2.2.15)
11
- actionpack (3.0.7)
12
- activemodel (= 3.0.7)
13
- activesupport (= 3.0.7)
14
- builder (~> 2.1.2)
15
- erubis (~> 2.6.6)
16
- i18n (~> 0.5.0)
17
- rack (~> 1.2.1)
18
- rack-mount (~> 0.6.14)
19
- rack-test (~> 0.5.7)
20
- tzinfo (~> 0.3.23)
21
- activemodel (3.0.7)
22
- activesupport (= 3.0.7)
23
- builder (~> 2.1.2)
24
- i18n (~> 0.5.0)
25
- activerecord (3.0.7)
26
- activemodel (= 3.0.7)
27
- activesupport (= 3.0.7)
28
- arel (~> 2.0.2)
29
- tzinfo (~> 0.3.23)
30
- activeresource (3.0.7)
31
- activemodel (= 3.0.7)
32
- activesupport (= 3.0.7)
33
- activesupport (3.0.7)
34
- arel (2.0.10)
7
+ actionmailer (3.1.3)
8
+ actionpack (= 3.1.3)
9
+ mail (~> 2.3.0)
10
+ actionpack (3.1.3)
11
+ activemodel (= 3.1.3)
12
+ activesupport (= 3.1.3)
13
+ builder (~> 3.0.0)
14
+ erubis (~> 2.7.0)
15
+ i18n (~> 0.6)
16
+ rack (~> 1.3.5)
17
+ rack-cache (~> 1.1)
18
+ rack-mount (~> 0.8.2)
19
+ rack-test (~> 0.6.1)
20
+ sprockets (~> 2.0.3)
21
+ activemodel (3.1.3)
22
+ activesupport (= 3.1.3)
23
+ builder (~> 3.0.0)
24
+ i18n (~> 0.6)
25
+ activerecord (3.1.3)
26
+ activemodel (= 3.1.3)
27
+ activesupport (= 3.1.3)
28
+ arel (~> 2.2.1)
29
+ tzinfo (~> 0.3.29)
30
+ activeresource (3.1.3)
31
+ activemodel (= 3.1.3)
32
+ activesupport (= 3.1.3)
33
+ activesupport (3.1.3)
34
+ multi_json (~> 1.0)
35
+ arel (2.2.1)
35
36
  bson (1.4.0)
36
37
  bson_ext (1.4.0)
37
- builder (2.1.2)
38
- columnize (0.3.2)
39
- diff-lcs (1.1.2)
40
- erubis (2.6.6)
41
- abstract (>= 1.0.0)
42
- fastercsv (1.5.3)
38
+ builder (3.0.0)
39
+ columnize (0.3.5)
40
+ diff-lcs (1.1.3)
41
+ erubis (2.7.0)
42
+ fastercsv (1.5.4)
43
43
  git (1.2.5)
44
- i18n (0.5.0)
45
- jeweler (1.6.1)
46
- bundler (~> 1.0.0)
44
+ hike (1.2.1)
45
+ i18n (0.6.0)
46
+ jeweler (1.6.4)
47
+ bundler (~> 1.0)
47
48
  git (>= 1.2.5)
48
49
  rake
49
- linecache (0.43)
50
- mail (2.2.19)
51
- activesupport (>= 2.3.6)
50
+ json (1.6.3)
51
+ linecache (0.46)
52
+ rbx-require-relative (> 0.0.4)
53
+ mail (2.3.0)
52
54
  i18n (>= 0.4.0)
53
55
  mime-types (~> 1.16)
54
56
  treetop (~> 1.4.8)
55
- mime-types (1.16)
56
- mocha (0.9.12)
57
+ metaclass (0.0.1)
58
+ mime-types (1.17.2)
59
+ mocha (0.10.0)
60
+ metaclass (~> 0.0.1)
57
61
  mongo (1.4.0)
58
62
  bson (= 1.4.0)
59
63
  mongoid (2.2.2)
60
64
  activemodel (~> 3.0)
61
65
  mongo (~> 1.3)
62
66
  tzinfo (~> 0.3.22)
63
- nokogiri (1.4.4)
64
- polyglot (0.3.1)
65
- rack (1.2.3)
66
- rack-mount (0.6.14)
67
+ multi_json (1.0.4)
68
+ nokogiri (1.5.0)
69
+ polyglot (0.3.3)
70
+ rack (1.3.5)
71
+ rack-cache (1.1)
72
+ rack (>= 0.4)
73
+ rack-mount (0.8.3)
67
74
  rack (>= 1.0.0)
68
- rack-test (0.5.7)
75
+ rack-ssl (1.3.2)
76
+ rack
77
+ rack-test (0.6.1)
69
78
  rack (>= 1.0)
70
- rails (3.0.7)
71
- actionmailer (= 3.0.7)
72
- actionpack (= 3.0.7)
73
- activerecord (= 3.0.7)
74
- activeresource (= 3.0.7)
75
- activesupport (= 3.0.7)
79
+ rails (3.1.3)
80
+ actionmailer (= 3.1.3)
81
+ actionpack (= 3.1.3)
82
+ activerecord (= 3.1.3)
83
+ activeresource (= 3.1.3)
84
+ activesupport (= 3.1.3)
76
85
  bundler (~> 1.0)
77
- railties (= 3.0.7)
78
- railties (3.0.7)
79
- actionpack (= 3.0.7)
80
- activesupport (= 3.0.7)
86
+ railties (= 3.1.3)
87
+ railties (3.1.3)
88
+ actionpack (= 3.1.3)
89
+ activesupport (= 3.1.3)
90
+ rack-ssl (~> 1.3.2)
81
91
  rake (>= 0.8.7)
82
- thor (~> 0.14.4)
92
+ rdoc (~> 3.4)
93
+ thor (~> 0.14.6)
83
94
  rake (0.9.2.2)
95
+ rbx-require-relative (0.0.5)
96
+ rdoc (3.11)
97
+ json (~> 1.4)
84
98
  rspec (2.6.0)
85
99
  rspec-core (~> 2.6.0)
86
100
  rspec-expectations (~> 2.6.0)
87
101
  rspec-mocks (~> 2.6.0)
88
- rspec-core (2.6.0)
102
+ rspec-core (2.6.4)
89
103
  rspec-expectations (2.6.0)
90
104
  diff-lcs (~> 1.1.2)
91
105
  rspec-mocks (2.6.0)
@@ -94,13 +108,19 @@ GEM
94
108
  ruby-debug-base (~> 0.10.4.0)
95
109
  ruby-debug-base (0.10.4)
96
110
  linecache (>= 0.3)
97
- sqlite3 (1.3.3)
111
+ sprockets (2.0.3)
112
+ hike (~> 1.2)
113
+ rack (~> 1.0)
114
+ tilt (~> 1.1, != 1.3.0)
115
+ sqlite3 (1.3.5)
98
116
  sqlite3-ruby (1.3.3)
99
117
  sqlite3 (>= 1.3.3)
100
118
  thor (0.14.6)
101
- treetop (1.4.9)
119
+ tilt (1.3.3)
120
+ treetop (1.4.10)
121
+ polyglot
102
122
  polyglot (>= 0.3.1)
103
- tzinfo (0.3.27)
123
+ tzinfo (0.3.31)
104
124
  will_paginate (2.3.15)
105
125
 
106
126
  PLATFORMS
@@ -67,8 +67,6 @@ Basic grid api:
67
67
 
68
68
  ``` ruby
69
69
  report = SimpleReport.new(
70
- :order => "group",
71
- :descending => true,
72
70
  :group_id => [1,2], :from_logins_count => 1,
73
71
  :category => "first",
74
72
  :order => :group,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5.0
@@ -0,0 +1,8 @@
1
+ <tr>
2
+ <% grid.columns.each do |column| %>
3
+ <th class="<%= datagrid_column_classes(grid, column) %>">
4
+ <%= column.header %>
5
+ <%= datagrid_order_for(grid, column) if column.order && options[:order]%>
6
+ </th>
7
+ <% end %>
8
+ </tr>
@@ -0,0 +1,7 @@
1
+ <tr class="<%= options[:cycle] && cycle(*options[:cycle]) %>">
2
+ <% grid.columns.each do |column| %>
3
+ <td class="<%= datagrid_column_classes(grid, column) %>">
4
+ <%= datagrid_format_value(grid, column, asset) %>
5
+ </td>
6
+ <% end %>
7
+ </tr>
@@ -0,0 +1,10 @@
1
+ <!--
2
+ Local variables:
3
+ * grid - instance of Datagrid
4
+ * assets - Array of database Entities
5
+ * options - passed options Hash
6
+ -->
7
+ <%= content_tag :table, options[:html] do %>
8
+ <%= datagrid_header(grid, options) %>
9
+ <%= datagrid_rows(grid, assets, options) %>
10
+ <% end %>
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "datagrid"
8
- s.version = "0.4.1"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bogdan Gusiev"]
12
- s.date = "2011-12-06"
12
+ s.date = "2012-01-03"
13
13
  s.description = "This allows you to easily build datagrid aka data tables with sortable columns and filters"
14
14
  s.email = "agresso@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -24,6 +24,9 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "Readme.markdown",
26
26
  "VERSION",
27
+ "app/views/datagrid/_head.html.erb",
28
+ "app/views/datagrid/_row.html.erb",
29
+ "app/views/datagrid/_table.html.erb",
27
30
  "datagrid.gemspec",
28
31
  "lib/datagrid.rb",
29
32
  "lib/datagrid/active_model.rb",
@@ -34,6 +37,7 @@ Gem::Specification.new do |s|
34
37
  "lib/datagrid/drivers/abstract_driver.rb",
35
38
  "lib/datagrid/drivers/active_record.rb",
36
39
  "lib/datagrid/drivers/mongoid.rb",
40
+ "lib/datagrid/engine.rb",
37
41
  "lib/datagrid/filters.rb",
38
42
  "lib/datagrid/filters/base_filter.rb",
39
43
  "lib/datagrid/filters/boolean_enum_filter.rb",
@@ -48,8 +52,10 @@ Gem::Specification.new do |s|
48
52
  "lib/datagrid/form_builder.rb",
49
53
  "lib/datagrid/helper.rb",
50
54
  "lib/datagrid/ordering.rb",
55
+ "lib/datagrid/renderer.rb",
51
56
  "lib/datagrid/rspec.rb",
52
57
  "lib/datagrid/utils.rb",
58
+ "lib/tasks/datagrid_tasks.rake",
53
59
  "spec/datagrid/active_model_spec.rb",
54
60
  "spec/datagrid/columns_spec.rb",
55
61
  "spec/datagrid/drivers/active_record_spec.rb",
@@ -61,12 +67,14 @@ Gem::Specification.new do |s|
61
67
  "spec/datagrid/form_builder_spec.rb",
62
68
  "spec/datagrid/helper_spec.rb",
63
69
  "spec/datagrid/ordering_spec.rb",
70
+ "spec/datagrid/utils_spec.rb",
64
71
  "spec/datagrid_spec.rb",
65
72
  "spec/spec_helper.rb",
66
- "spec/support/equal_to_dom.rb",
73
+ "spec/support/active_record.rb",
74
+ "spec/support/matchers.rb",
67
75
  "spec/support/mongoid.rb",
68
- "spec/support/schema.rb",
69
- "spec/support/simple_report.rb"
76
+ "spec/support/simple_report.rb",
77
+ "spec/support/test_partials/_actions.html.erb"
70
78
  ]
71
79
  s.homepage = "http://github.com/bogdan/datagrid"
72
80
  s.licenses = ["MIT"]
@@ -6,6 +6,9 @@ require "datagrid/ordering"
6
6
 
7
7
  require "datagrid/helper"
8
8
  require "datagrid/form_builder"
9
+ require "datagrid/renderer"
10
+
11
+ require "datagrid/engine"
9
12
 
10
13
  module Datagrid
11
14
 
@@ -12,15 +12,16 @@ module Datagrid
12
12
 
13
13
  include Datagrid::Core
14
14
 
15
-
16
15
  end
17
16
  base.send :include, InstanceMethods
18
17
  end # self.included
19
18
 
20
19
  module ClassMethods
21
20
 
22
- def columns
23
- @columns ||= []
21
+ def columns(options = {})
22
+ (@columns ||= []).reject do |column|
23
+ options[:data] && column.html?
24
+ end
24
25
  end
25
26
 
26
27
  def column(name, options = {}, &block)
@@ -28,7 +29,8 @@ module Datagrid
28
29
  block ||= lambda do |model|
29
30
  model.send(name)
30
31
  end
31
- self.columns << Datagrid::Columns::Column.new(self, name, options, &block)
32
+ @columns ||= []
33
+ @columns << Datagrid::Columns::Column.new(self, name, options, &block)
32
34
  end
33
35
 
34
36
  def column_by_name(name)
@@ -42,12 +44,12 @@ module Datagrid
42
44
 
43
45
  # Returns <tt>Array</tt> of human readable column names. See also "Localization" section
44
46
  def header
45
- self.class.columns.map(&:header)
47
+ self.data_columns.map(&:header)
46
48
  end
47
49
 
48
50
  # Returns <tt>Array</tt> column values for given asset
49
51
  def row_for(asset)
50
- self.class.columns.map do |column|
52
+ self.data_columns.map do |column|
51
53
  column.value(asset, self)
52
54
  end
53
55
  end
@@ -55,7 +57,7 @@ module Datagrid
55
57
  # Returns <tt>Hash</tt> where keys are column names and values are column values for the given asset
56
58
  def hash_for(asset)
57
59
  result = {}
58
- self.class.columns.each do |column|
60
+ self.data_columns.each do |column|
59
61
  result[column.name] = column.value(asset, self)
60
62
  end
61
63
  result
@@ -94,8 +96,12 @@ module Datagrid
94
96
  end
95
97
  end
96
98
 
97
- def columns
98
- self.class.columns
99
+ def columns(options ={})
100
+ self.class.columns(options)
101
+ end
102
+
103
+ def data_columns
104
+ self.columns(:data => true)
99
105
  end
100
106
 
101
107
  def column_by_name(name)
@@ -7,17 +7,20 @@ class Datagrid::Columns::Column
7
7
  self.name = name.to_sym
8
8
  self.options = options
9
9
  self.block = block
10
+ if format
11
+ ::Datagrid::Utils.warn_once(":format column option is deprecated. Use :url or :html option instead.")
12
+ end
10
13
  end
11
14
 
12
- def value(model, report)
13
- value_for(model, report)
15
+ def value(model, grid)
16
+ value_for(model, grid)
14
17
  end
15
18
 
16
- def value_for(model, report)
19
+ def value_for(model, grid)
17
20
  if self.block.arity == 1
18
21
  self.block.call(model)
19
22
  elsif self.block.arity == 2
20
- self.block.call(model, report)
23
+ self.block.call(model, grid)
21
24
  else
22
25
  model.instance_eval(&self.block)
23
26
  end
@@ -49,4 +52,10 @@ class Datagrid::Columns::Column
49
52
  self.options[:order_desc]
50
53
  end
51
54
 
55
+
56
+ def html?
57
+ !! self.options[:html]
58
+ end
59
+
60
+
52
61
  end
@@ -3,6 +3,7 @@ module Datagrid
3
3
  class ActiveRecord < AbstractDriver
4
4
 
5
5
  def self.match?(scope)
6
+ return false unless defined?(::ActiveRecord)
6
7
  if scope.is_a?(Class)
7
8
  scope.ancestors.include?(::ActiveRecord::Base)
8
9
  else
@@ -3,6 +3,7 @@ module Datagrid
3
3
  class Mongoid < AbstractDriver
4
4
 
5
5
  def self.match?(scope)
6
+ return false unless defined?(::Mongoid)
6
7
  if scope.is_a?(Class)
7
8
  scope.ancestors.include?(::Mongoid::Document)
8
9
  else
@@ -0,0 +1,12 @@
1
+ require "rails/engine"
2
+
3
+ module Datagrid
4
+ class Engine < ::Rails::Engine
5
+ initializer "datagrid.helpers" do
6
+ #TODO: check why it doesn't work
7
+ ActiveSupport.on_load :action_view do
8
+ include Datagrid::Helper
9
+ end
10
+ end
11
+ end
12
+ end
@@ -7,7 +7,7 @@ module Datagrid
7
7
  filter = get_filter(filter_or_attribute)
8
8
  options[:class] ||= ""
9
9
  options[:class] += " " unless options[:class].blank?
10
- options[:class] += "#{filter.name} #{datagrid_html_class(filter.class)}"
10
+ options[:class] += "#{filter.name} #{datagrid_filter_html_class(filter)}"
11
11
  self.send(datagrid_filter_method(filter), filter, options)
12
12
  end
13
13
 
@@ -67,12 +67,12 @@ module Datagrid
67
67
  end
68
68
  end
69
69
 
70
- def datagrid_html_class(klass)
71
- klass.to_s.split("::").last.underscore
70
+ def datagrid_filter_html_class(filter)
71
+ filter.class.to_s.demodulize.underscore
72
72
  end
73
73
 
74
74
  def datagrid_filter_method(filter)
75
- :"datagrid_#{filter.class.to_s.underscore.split('/').last}"
75
+ :"datagrid_#{filter.class.to_s.demodulize.underscore}"
76
76
  end
77
77
 
78
78
  class Error < StandardError
@@ -1,83 +1,39 @@
1
+ require "datagrid/engine"
1
2
  require "action_view"
2
3
 
3
4
  module Datagrid
4
5
  module Helper
5
6
 
6
7
  def datagrid_format_value(report, column, asset)
7
- value = column.value(asset, report)
8
- url = column.options[:url] && column.options[:url].call(asset)
9
- if url
10
- link_to(value, url)
11
- else
12
- case column.format
13
- when :url
14
- link_to(column.label ? asset.send(column.label) : I18n.t("datagrid.table.url_label", :default => "URL"), value)
15
- else
16
- _safe(value)
17
- end
18
- end
8
+ datagrid_renderer.format_value(report, column, asset)
19
9
  end
20
10
 
21
11
  def datagrid_table(report, *args)
22
- options = args.extract_options!
23
- html = options[:html] || {}
24
- html[:class] ||= "datagrid"
25
- assets = args.any? ? args.shift : report.assets
26
- paginate = options[:paginate]
27
- assets = assets.paginate(paginate) if paginate
28
- content = content_tag(:tr, datagrid_header(report, options)) + datagrid_rows(report, assets, options)
29
- content_tag(:table, content, html)
12
+ datagrid_renderer.table(report, *args)
30
13
  end
31
14
 
32
-
33
15
  def datagrid_header(grid, options = {})
34
- header = empty_string
35
- options[:order] = true unless options.has_key?(:order)
36
- grid.columns.each do |column|
37
- data = _safe(column.header)
38
- if options[:order] && column.order
39
- data << datagrid_order_for(grid, column)
40
- end
41
- header << content_tag(:th, data, :class => column.name)
42
- end
43
- header
16
+ datagrid_renderer.header(grid, options)
44
17
  end
45
18
 
46
- def datagrid_rows(report, assets, options)
47
- columns = report.columns
48
- result = assets.map do |asset|
49
- content = columns.map do |column|
50
- content_tag(:td, datagrid_format_value(report, column, asset), :class => column.name)
51
- end.join(empty_string)
52
- content_tag(:tr, _safe(content), :class => options[:cycle] && cycle(*options[:cycle]))
53
- end.join(empty_string)
54
- _safe(result)
19
+ def datagrid_rows(report, assets, options = {})
20
+ datagrid_renderer.rows(report, assets, options)
55
21
  end
56
22
 
57
23
  def datagrid_order_for(grid, column)
58
- content_tag(:div, :class => "order") do
59
- link_to(
60
- I18n.t("datagrid.table.order.asc", :default => "ASC"),
61
- url_for(grid.param_name => grid.attributes.merge(:order => column.name, :descending => false)),
62
- :class => "order asc"
63
- ) + " " + link_to(
64
- I18n.t("datagrid.table.order.desc", :default => "DESC"),
65
- url_for(grid.param_name => grid.attributes.merge(:order => column.name, :descending => true )),
66
- :class => "order desc"
67
- )
68
- end
24
+ datagrid_renderer.order_for(grid, column)
69
25
  end
70
26
 
71
27
  protected
72
- def empty_string
73
- _safe("")
28
+
29
+ def datagrid_renderer
30
+ Renderer.for(self)
74
31
  end
75
32
 
76
- def _safe(string)
77
- string.respond_to?(:html_safe) ? string.html_safe : string
33
+ def datagrid_column_classes(grid, column)
34
+ order_class = grid.order == column.name ? ["ordered", grid.descending ? "desc" : "asc"] : nil
35
+ [column.name, order_class].compact.join(" ")
78
36
  end
79
37
  end
80
-
81
- ::ActionView::Base.send(:include, ::Datagrid::Helper)
82
-
83
38
  end
39
+ ActionView::Base.send(:include, Datagrid::Helper)
@@ -0,0 +1,73 @@
1
+ require "action_view"
2
+
3
+ module Datagrid
4
+ class Renderer
5
+
6
+ def self.for(template)
7
+ new(template)
8
+ end
9
+
10
+ def initialize(template)
11
+ @template = template
12
+ end
13
+
14
+ def format_value(grid, column, asset)
15
+ value = column.html? ? @template.instance_exec(asset, &column.block) : column.value(asset, grid)
16
+ url = column.options[:url] && column.options[:url].call(asset)
17
+ if url
18
+ @template.link_to(value, url)
19
+ else
20
+ case column.format
21
+ when :url
22
+ @template.link_to(column.label ? asset.send(column.label) : I18n.t("datagrid.table.url_label", :default => "URL"), value)
23
+ else
24
+ _safe(value)
25
+ end
26
+ end
27
+ end
28
+
29
+ def table(grid, *args)
30
+ options = args.extract_options!
31
+ options[:html] ||= {}
32
+ options[:html][:class] ||= "datagrid #{grid.class.to_s.underscore.demodulize}"
33
+ assets = args.any? ? args.shift : grid.assets
34
+ paginate = options[:paginate]
35
+ assets = assets.paginate(paginate) if paginate
36
+
37
+ @template.render :partial => "datagrid/table", :locals => {:grid => grid, :options => options, :assets => assets}
38
+ end
39
+
40
+ def header(grid, options = {})
41
+ options[:order] = true unless options.has_key?(:order)
42
+
43
+ @template.render :partial => "datagrid/head", :locals => {:grid => grid, :options => options}
44
+ end
45
+
46
+ def rows(grid, assets, options = {})
47
+ result = assets.map do |asset|
48
+ @template.render :partial => "datagrid/row", :locals => {:grid => grid, :options => options, :asset => asset}
49
+ end.join
50
+
51
+ _safe(result)
52
+ end
53
+
54
+ def order_for(grid, column)
55
+ @template.content_tag(:div, :class => "order") do
56
+ @template.link_to(
57
+ I18n.t("datagrid.table.order.asc", :default => "ASC"),
58
+ @template.url_for(grid.param_name => grid.attributes.merge(:order => column.name, :descending => false)),
59
+ :class => "order asc"
60
+ ) + " " + @template.link_to(
61
+ I18n.t("datagrid.table.order.desc", :default => "DESC"),
62
+ @template.url_for(grid.param_name => grid.attributes.merge(:order => column.name, :descending => true )),
63
+ :class => "order desc"
64
+ )
65
+ end
66
+ end
67
+
68
+
69
+ def _safe(string)
70
+ string.respond_to?(:html_safe) ? string.html_safe : string
71
+ end
72
+ end
73
+ end
@@ -1,5 +1,6 @@
1
1
  require "datagrid"
2
2
 
3
+ #TODO: refactor this experimental shit
3
4
  shared_examples_for "Datagrid" do
4
5
  describe "as Datagrid" do
5
6
 
@@ -9,7 +10,7 @@ shared_examples_for "Datagrid" do
9
10
 
10
11
  its(:data) {should_not be_empty}
11
12
 
12
- described_class.columns.each do |column|
13
+ described_class.columns(:data => true).each do |column|
13
14
  describe "column ##{column.name}" do
14
15
 
15
16
  it "should has value in #data_hash" do
@@ -7,6 +7,16 @@ module Datagrid
7
7
  def booleanize(value)
8
8
  TRUTH.include?(value)
9
9
  end
10
+
11
+ def warn_once(message)
12
+ @warnings ||= {}
13
+ if @warnings[message]
14
+ false
15
+ else
16
+ warn message
17
+ @warnings[message] = true
18
+ end
19
+ end
10
20
  end
11
21
  end
12
22
  end
@@ -0,0 +1,19 @@
1
+ namespace :datagrid do
2
+
3
+ desc "Copy table partials into rails application"
4
+ task :copy_partials do
5
+ require "fileutils"
6
+ def copy_template(path)
7
+ gem_app = File.expand_path("../../../app", __FILE__)
8
+ rails_app = (Rails.root + "app").to_s
9
+ full_path = "#{rails_app}/#{File.dirname path}"
10
+ puts "* copy #{full_path}"
11
+ FileUtils.mkdir_p full_path
12
+ FileUtils.cp "#{gem_app}/#{path}", full_path
13
+ end
14
+ copy_template "views/datagrid/_table.html.erb"
15
+ copy_template "views/datagrid/_head.html.erb"
16
+ copy_template "views/datagrid/_row.html.erb"
17
+ end
18
+
19
+ end
@@ -13,6 +13,10 @@ describe Datagrid::Columns do
13
13
  let!(:entry) { Entry.create!(
14
14
  :group => group, :name => "Star", :disabled => false, :confirmed => false, :category => "first"
15
15
  ) }
16
+
17
+ it "should have data columns without html columns" do
18
+ subject.data_columns.size.should == subject.columns.size - 1
19
+ end
16
20
  it "should build rows of data" do
17
21
  subject.rows.should == [["Pop", "Star"]]
18
22
  end
@@ -34,9 +38,9 @@ describe Datagrid::Columns do
34
38
  }
35
39
  end
36
40
 
37
- it "should support csv export" do
38
- subject.to_csv.should == "Group,Name\nPop,Star\n"
39
- end
41
+ it "should support csv export" do
42
+ subject.to_csv.should == "Group,Name\nPop,Star\n"
43
+ end
40
44
  end
41
45
 
42
46
  it "should support columns with model and report arguments" do
@@ -16,13 +16,4 @@ describe Datagrid::Filters::EnumFilter do
16
16
  end.class.filter_by_name(:group_id).select.should == [1,2]
17
17
  end
18
18
 
19
- it "should stack with other filters" do
20
- Entry.create(:name => "ZZ", :category => "first")
21
- report = test_report(:name => "Pop", :category => "first") do
22
- scope { Entry }
23
- filter(:name)
24
- filter(:category, :enum, :select => ["first", "second"])
25
- end
26
- report.assets.should be_empty
27
- end
28
19
  end
@@ -9,6 +9,16 @@ describe Datagrid::Filters do
9
9
  end.created_at.should == Date.today
10
10
  end
11
11
 
12
+ it "should stack with other filters" do
13
+ Entry.create(:name => "ZZ", :category => "first")
14
+ report = test_report(:name => "Pop", :category => "first") do
15
+ scope { Entry }
16
+ filter(:name)
17
+ filter(:category, :enum, :select => ["first", "second"])
18
+ end
19
+ report.assets.should be_empty
20
+ end
21
+
12
22
  it "should not support array argument for not multiple filter" do
13
23
  report = test_report do
14
24
  scope {Entry}
@@ -20,7 +30,7 @@ describe Datagrid::Filters do
20
30
  end
21
31
 
22
32
 
23
- it "should initialize report Scope table not exists" do
33
+ it "should initialize when report Scope table not exists" do
24
34
  class ModelWithoutTable < ActiveRecord::Base; end
25
35
  ModelWithoutTable.should_not be_table_exists
26
36
  class TheReport
@@ -3,15 +3,22 @@ require "will_paginate"
3
3
  require "active_support/core_ext/hash"
4
4
  require "active_support/core_ext/object"
5
5
 
6
+ require 'datagrid/renderer'
7
+
6
8
  describe Datagrid::Helper do
7
- subject {ActionView::Base.new}
9
+ subject do
10
+ template = ActionView::Base.new
11
+ template.view_paths << File.expand_path("../../../app/views", __FILE__)
12
+ template.view_paths << File.expand_path("../../support/test_partials", __FILE__)
13
+ template
14
+ end
8
15
 
9
16
  before(:each) do
10
17
  subject.stub!(:params).and_return({})
11
18
  subject.stub(:url_for) do |options|
12
19
  options.to_param
13
20
  end
14
-
21
+
15
22
  end
16
23
 
17
24
  let(:group) { Group.create!(:name => "Pop") }
@@ -21,108 +28,119 @@ describe Datagrid::Helper do
21
28
  let(:grid) { SimpleReport.new }
22
29
 
23
30
  describe ".datagrid_table" do
24
- before(:each) do
25
- subject.stub!(:datagrid_order_for).and_return(subject.content_tag(:div, "", :class => "order"))
31
+ it "should have grid class as html class on table" do
32
+ subject.datagrid_table(grid).should match_css_pattern(
33
+ "table.datagrid.simple_report" => 1
34
+ )
26
35
  end
27
36
  it "should return data table html" do
28
- subject.datagrid_table(grid).should equal_to_dom(<<-HTML)
29
- <table class="datagrid">
30
- <tr>
31
- <th class="group">Group<div class="order"></div>
32
- </th>
33
- <th class="name">Name<div class="order"></div>
34
- </th>
35
- </tr>
36
-
37
- <tr>
38
- <td class="group">Pop</td>
39
- <td class="name">Star</td>
40
- </tr>
41
- </table>
42
- HTML
37
+ datagrid_table = subject.datagrid_table(grid)
38
+
39
+ datagrid_table.should match_css_pattern({
40
+ "table.datagrid tr th.group div.order" => 1,
41
+ "table.datagrid tr th.group" => /Group.*/,
42
+ "table.datagrid tr th.name div.order" => 1,
43
+ "table.datagrid tr th.name" => /Name.*/,
44
+ "table.datagrid tr td.group" => "Pop",
45
+ "table.datagrid tr td.name" => "Star"
46
+ })
43
47
  end
48
+
44
49
  it "should support giving assets explicitly" do
45
50
  other_entry = Entry.create!(entry.attributes)
46
- subject.datagrid_table(grid, [entry]).should equal_to_dom(<<-HTML)
47
- <table class="datagrid">
48
- <tr>
49
- <th class="group">Group<div class="order"></div>
50
- </th>
51
- <th class="name">Name<div class="order"></div>
52
- </th>
53
- </tr>
54
-
55
- <tr>
56
- <td class="group">Pop</td>
57
- <td class="name">Star</td>
58
- </tr>
59
- </table>
60
- HTML
61
- end
62
- it "should support giving assets implicitly" do
63
- other_entry = Entry.create!(entry.attributes)
64
- subject.datagrid_table(grid, [entry]).should equal_to_dom(<<-HTML)
65
- <table class="datagrid">
66
- <tr>
67
- <th class="group">Group<div class="order"></div>
68
- </th>
69
- <th class="name">Name<div class="order"></div>
70
- </th>
71
- </tr>
72
-
73
- <tr>
74
- <td class="group">Pop</td>
75
- <td class="name">Star</td>
76
- </tr>
77
- </table>
78
- HTML
51
+ datagrid_table = subject.datagrid_table(grid, [entry])
52
+
53
+ datagrid_table.should match_css_pattern({
54
+ "table.datagrid tr th.group div.order" => 1,
55
+ "table.datagrid tr th.group" => /Group.*/,
56
+ "table.datagrid tr th.name div.order" => 1,
57
+ "table.datagrid tr th.name" => /Name.*/,
58
+ "table.datagrid tr td.group" => "Pop",
59
+ "table.datagrid tr td.name" => "Star"
60
+ })
79
61
  end
80
62
 
81
63
  it "should support cycle option" do
82
- subject.datagrid_rows(grid, [entry], :cycle => ["odd", "even"]).should equal_to_dom(<<-HTML)
83
- <tr class="odd">
84
- <td class="group">Pop</td>
85
- <td class="name">Star</td>
86
- </tr>
87
- HTML
64
+ subject.datagrid_rows(grid, [entry], :cycle => ["odd", "even"]).should match_css_pattern({
65
+ "tr.odd td.group" => "Pop",
66
+ "tr.odd td.name" => "Star"
67
+ })
68
+
88
69
  end
89
70
 
90
- it "should support urls" do
91
- rp = test_report do
92
- scope { Entry }
93
- column(:name, :url => lambda {|model| model.name})
94
- end
95
- subject.datagrid_rows(rp, [entry], {}).should equal_to_dom(<<-HTML)
96
- <tr><td class="name"><a href="Star">Star</a></td></tr>
97
- HTML
71
+ it "should support no order given" do
72
+ subject.datagrid_table(grid, [entry], :order => false).should match_css_pattern("table.datagrid th .order" => 0)
98
73
  end
99
- it "should support conditional urls" do
100
- rp = test_report do
101
- scope { Entry }
102
- column(:name, :url => lambda {false})
74
+
75
+ describe ".datagrid_rows" do
76
+
77
+ it "should support urls" do
78
+ rp = test_report do
79
+ scope { Entry }
80
+ column(:name, :url => lambda {|model| model.name})
81
+ end
82
+ subject.datagrid_rows(rp, [entry]).should match_css_pattern(
83
+ "tr td.name a[href=Star]" => "Star"
84
+ )
85
+ end
86
+ it "should support conditional urls" do
87
+ rp = test_report do
88
+ scope { Entry }
89
+ column(:name, :url => lambda {|model| false})
90
+ end
91
+ subject.datagrid_rows(rp, [entry]).should match_css_pattern(
92
+ "tr td.name" => "Star"
93
+ )
94
+
95
+ end
96
+ it "should add ordering classes to column" do
97
+ rp = test_report(:order => :name) do
98
+ scope { Entry }
99
+ column(:name)
100
+ end
101
+ subject.datagrid_rows(rp, [entry]).should match_css_pattern(
102
+ "tr td.name.ordered.asc" => "Star"
103
+ )
104
+
105
+ end
106
+ it "should add ordering classes to column" do
107
+ rp = test_report(:order => :name, :descending => true) do
108
+ scope { Entry }
109
+ column(:name)
110
+ end
111
+ subject.datagrid_rows(rp, [entry]).should match_css_pattern(
112
+ "tr td.name.ordered.desc" => "Star"
113
+ )
103
114
  end
104
- subject.datagrid_rows(rp, [entry], {}).should equal_to_dom(<<-HTML)
105
- <tr><td class="name">Star</td></tr>
106
- HTML
107
- end
108
- end
109
115
 
110
- describe ".datagrid_order_for" do
111
- it "should render ordreing layout" do
112
- class OrderedGrid
113
- include Datagrid
114
- scope { Entry }
115
- column(:category)
116
+ it "should render html columns" do
117
+
118
+ rp = test_report do
119
+ scope { Entry }
120
+ column(:name, :html => true) do |model|
121
+ content_tag(:span, model.name)
122
+ end
123
+ end
124
+ subject.datagrid_rows(rp, [entry]).should match_css_pattern(
125
+ "tr td.name span" => "Star"
126
+ )
116
127
  end
117
- report = OrderedGrid.new(:descending => true, :order => :category)
118
- subject.datagrid_order_for(report, report.column_by_name(:category)).should equal_to_dom(<<-HTML)
128
+ end
129
+
130
+ describe ".datagrid_order_for" do
131
+ it "should render ordreing layout" do
132
+ class OrderedGrid
133
+ include Datagrid
134
+ scope { Entry }
135
+ column(:category)
136
+ end
137
+ grid = OrderedGrid.new(:descending => true, :order => :category)
138
+ subject.datagrid_order_for(grid, grid.column_by_name(:category)).should equal_to_dom(<<-HTML)
119
139
  <div class="order">
120
140
  <a href="ordered_grid%5Bdescending%5D=false&amp;ordered_grid%5Border%5D=category" class="order asc">ASC</a> <a href="ordered_grid%5Bdescending%5D=true&amp;ordered_grid%5Border%5D=category" class="order desc">DESC</a>
121
141
  </div>
122
- HTML
142
+ HTML
143
+ end
123
144
  end
124
-
125
145
  end
126
-
127
-
128
146
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Datagrid::Utils do
4
+
5
+
6
+ describe ".warn_once" do
7
+ it "should work" do
8
+ silence_warnings do
9
+ Datagrid::Utils.warn_once("hello").should be_true
10
+ end
11
+ Datagrid::Utils.warn_once("hello").should be_false
12
+ end
13
+ end
14
+ end
@@ -19,7 +19,7 @@ require 'datagrid'
19
19
  require "discover"
20
20
  begin
21
21
  require 'ruby-debug'
22
- rescue
22
+ rescue LoadError
23
23
  end
24
24
  require 'rspec'
25
25
  require "logger"
@@ -27,6 +27,7 @@ require "logger"
27
27
  File.open('spec.log', "w").close
28
28
  TEST_LOGGER = Logger.new('spec.log')
29
29
 
30
+
30
31
  RSpec.configure do |config|
31
32
 
32
33
 
@@ -0,0 +1,93 @@
1
+ require "nokogiri"
2
+
3
+ def equal_to_dom(text)
4
+ EqualToDom.new(text)
5
+ end
6
+
7
+
8
+ def include_dom(text)
9
+ IncludeDom.new(text)
10
+ end
11
+
12
+ def match_css_pattern(pattern)
13
+ CssPattern.new(pattern)
14
+ end
15
+
16
+
17
+ class IncludeDom
18
+ def initialize(expectation)
19
+ @expectation = Nokogiri::HTML::DocumentFragment.parse(expectation.strip).to_s
20
+ end
21
+
22
+ def matches?(text)
23
+ @matcher = Nokogiri::HTML::DocumentFragment.parse(text.strip).to_s
24
+ @matcher == @expectation
25
+ end
26
+
27
+ def failure_message
28
+ "Expected dom \n#{@matcher.inspect}\n to include \n#{@expectation.inspect}\n, but it wasn't"
29
+ end
30
+ end
31
+
32
+
33
+ class EqualToDom
34
+
35
+ def initialize(expectation)
36
+ @expectation = Nokogiri::HTML::DocumentFragment.parse(expectation.strip).to_s
37
+ end
38
+
39
+ def matches?(text)
40
+ @matcher = Nokogiri::HTML::DocumentFragment.parse(text.strip).to_s
41
+ @matcher == @expectation
42
+ end
43
+
44
+ def failure_message
45
+ "Expected dom #{@matcher} to match #{@expectation}, but it wasn't"
46
+ end
47
+ end
48
+
49
+
50
+ class CssPattern
51
+ def initialize(pattern)
52
+ @css_pattern = pattern
53
+ end
54
+
55
+ def error!(message)
56
+ @error_message = message
57
+ false
58
+ end
59
+
60
+ def failure_message
61
+ @error_message || ""
62
+ end
63
+
64
+ def matches?(text)
65
+ text = text.clone.force_encoding("UTF-8") if "1.9.3".respond_to? :force_encoding
66
+
67
+ @matcher = Nokogiri::HTML::DocumentFragment.parse(text)
68
+ @css_pattern.each do |css, amount_or_pattern_or_string_or_proc|
69
+ path = @matcher.css(css)
70
+ if amount_or_pattern_or_string_or_proc.is_a?(String) or amount_or_pattern_or_string_or_proc.is_a?(Regexp)
71
+ pattern_or_string = amount_or_pattern_or_string_or_proc
72
+ html = path.inner_html
73
+ if !html.match(pattern_or_string)
74
+ return error!("#{css.inspect} did not match #{pattern_or_string.inspect}. It was \n:#{html.inspect}")
75
+ end
76
+ elsif amount_or_pattern_or_string_or_proc.is_a? Fixnum
77
+ expected_amount = amount_or_pattern_or_string_or_proc
78
+ amount = path.size
79
+ if amount != expected_amount
80
+ return error!("did not find #{css.inspect} #{expected_amount.inspect} times. It was #{amount.inspect}")
81
+ end
82
+ elsif amount_or_pattern_or_string_or_proc.is_a? Proc
83
+ if !amount_or_pattern_or_string_or_proc.call(path)
84
+ return error!("#{css.inspect} did not validate (proc must not return a falsy value)")
85
+ end
86
+ else
87
+ raise "Instance of String, Rexexp, Proc or Fixnum required"
88
+ end
89
+ true
90
+ end
91
+ end
92
+
93
+ end
@@ -36,6 +36,10 @@ class SimpleReport
36
36
  user.name
37
37
  end
38
38
 
39
+ column(:actions, :html => true) do |model|
40
+ render :partial => "actions", :locals => {:model => model}
41
+ end
42
+
39
43
  def param_name
40
44
  :report
41
45
  end
@@ -0,0 +1 @@
1
+ <%= "No action for #{model.name}" -%>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datagrid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 1
10
- version: 0.4.1
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bogdan Gusiev
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-12-06 00:00:00 Z
18
+ date: 2012-01-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :runtime
@@ -259,6 +259,9 @@ files:
259
259
  - Rakefile
260
260
  - Readme.markdown
261
261
  - VERSION
262
+ - app/views/datagrid/_head.html.erb
263
+ - app/views/datagrid/_row.html.erb
264
+ - app/views/datagrid/_table.html.erb
262
265
  - datagrid.gemspec
263
266
  - lib/datagrid.rb
264
267
  - lib/datagrid/active_model.rb
@@ -269,6 +272,7 @@ files:
269
272
  - lib/datagrid/drivers/abstract_driver.rb
270
273
  - lib/datagrid/drivers/active_record.rb
271
274
  - lib/datagrid/drivers/mongoid.rb
275
+ - lib/datagrid/engine.rb
272
276
  - lib/datagrid/filters.rb
273
277
  - lib/datagrid/filters/base_filter.rb
274
278
  - lib/datagrid/filters/boolean_enum_filter.rb
@@ -283,8 +287,10 @@ files:
283
287
  - lib/datagrid/form_builder.rb
284
288
  - lib/datagrid/helper.rb
285
289
  - lib/datagrid/ordering.rb
290
+ - lib/datagrid/renderer.rb
286
291
  - lib/datagrid/rspec.rb
287
292
  - lib/datagrid/utils.rb
293
+ - lib/tasks/datagrid_tasks.rake
288
294
  - spec/datagrid/active_model_spec.rb
289
295
  - spec/datagrid/columns_spec.rb
290
296
  - spec/datagrid/drivers/active_record_spec.rb
@@ -296,12 +302,14 @@ files:
296
302
  - spec/datagrid/form_builder_spec.rb
297
303
  - spec/datagrid/helper_spec.rb
298
304
  - spec/datagrid/ordering_spec.rb
305
+ - spec/datagrid/utils_spec.rb
299
306
  - spec/datagrid_spec.rb
300
307
  - spec/spec_helper.rb
301
- - spec/support/equal_to_dom.rb
308
+ - spec/support/active_record.rb
309
+ - spec/support/matchers.rb
302
310
  - spec/support/mongoid.rb
303
- - spec/support/schema.rb
304
311
  - spec/support/simple_report.rb
312
+ - spec/support/test_partials/_actions.html.erb
305
313
  homepage: http://github.com/bogdan/datagrid
306
314
  licenses:
307
315
  - MIT
@@ -1,42 +0,0 @@
1
- require "nokogiri"
2
-
3
- def equal_to_dom(text)
4
- EqualToDom.new(text)
5
- end
6
-
7
-
8
- def include_dom(text)
9
- IncludeDom.new(text)
10
- end
11
-
12
- class IncludeDom
13
- def initialize(expectation)
14
- @expectation = Nokogiri::HTML::DocumentFragment.parse(expectation).to_s
15
- end
16
-
17
- def matches?(text)
18
- @matcher = Nokogiri::HTML::DocumentFragment.parse(text).to_s
19
- @matcher == @expectation
20
- end
21
-
22
- def failure_message
23
- "Expected dom \n#{@matcher.inspect}\n to include \n#{@expectation.inspect}\n, but it wasn't"
24
- end
25
- end
26
-
27
-
28
- class EqualToDom
29
-
30
- def initialize(expectation)
31
- @expectation = Nokogiri::HTML::DocumentFragment.parse(expectation).to_s
32
- end
33
-
34
- def matches?(text)
35
- @matcher = Nokogiri::HTML::DocumentFragment.parse(text).to_s
36
- @matcher == @expectation
37
- end
38
-
39
- def failure_message
40
- "Expected dom #{@matcher} to match #{@expectation}, but it wasn't"
41
- end
42
- end