datagrid 0.2.0 → 0.3.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/Gemfile CHANGED
@@ -17,7 +17,8 @@ group :development do
17
17
  gem "bundler", "~> 1.0.0"
18
18
  gem "jeweler", "~> 1.6.0"
19
19
  gem "rcov", ">= 0"
20
- gem "ruby-debug"
20
+ gem "ruby-debug", :platform => "mri_18"
21
+ #gem "ruby-debug19", :platform => "mri_19"
21
22
  gem "sqlite3-ruby"
22
23
  gem "fastercsv"
23
24
  gem "nokogiri"
@@ -41,9 +41,9 @@ class SimpleReport
41
41
  filter(:category, :enum, :select => ["first", "second"])
42
42
  filter(:disabled, :eboolean)
43
43
  filter(:confirmed, :boolean)
44
- filter(:group_id, :multiple => true)
44
+ filter(:group_id, :integer, :multiple => true)
45
45
  integer_range_filter(:logins_count, :integer)
46
- filter(:group_name, :header => "Group") do |value|
46
+ filter(:group_name, :string, :header => "Group") do |value|
47
47
  self.joins(:group).where(:groups => {:name => value})
48
48
  end
49
49
 
@@ -66,7 +66,14 @@ end
66
66
  Basic grid api:
67
67
 
68
68
  ``` ruby
69
- report = SimpleReport.new(:order => "group", :descending => true, :group_id => [1,2], :from_logins_count => 1, :category => "first")
69
+ report = SimpleReport.new(
70
+ :order => "group",
71
+ :descending => true,
72
+ :group_id => [1,2], :from_logins_count => 1,
73
+ :category => "first",
74
+ :order => :group,
75
+ :descending => true
76
+ )
70
77
 
71
78
  report.assets # => Array of User instances:
72
79
  # SELECT * FROM users WHERE users.group_id in (1,2) AND users.logins_count >= 1 AND users.category = 'first' ORDER BY groups.name DESC
@@ -85,7 +92,13 @@ report.to_csv # => Yes, it is
85
92
  ### Scope
86
93
 
87
94
  Default scope of objects to filter and display.
88
- In common case it is `ActiveRecord::Base` subclass with some generic scopes like in example above.
95
+ In common case it is `ActiveRecord::Base` subclass with some generic scopes like in example above:
96
+
97
+ ``` ruby
98
+ scope do
99
+ User.includes(:group)
100
+ end
101
+ ```
89
102
 
90
103
  ### Filters
91
104
 
@@ -104,16 +117,18 @@ Datagrid supports different type of filters including:
104
117
  * boolean
105
118
  * eboolean - the select of "yes", "no" and any
106
119
  * enum
120
+ * string
107
121
 
108
- Read more about filters here:
122
+ [More about filters](https://github.com/bogdan/datagrid/wiki/Filters)
109
123
 
110
124
 
111
125
  ### Columns
112
126
 
113
127
  Each column is represented by name and code block to calculate the value.
114
- Grids are sortable by it's columns. Ordering is controller by `#order` and `#descending` attributes.
128
+ Some formatting options are also available.
129
+ Each column is sortable.
115
130
 
116
- More information about columns here:
131
+ [More about columns](https://github.com/bogdan/datagrid/wiki/Columns)
117
132
 
118
133
 
119
134
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{datagrid}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.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 = %q{2011-06-22}
12
+ s.date = %q{2011-07-01}
13
13
  s.description = %q{This allows you to easily build datagrid aka data tables with sortable columns and filters}
14
14
  s.email = %q{agresso@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -39,6 +39,7 @@ Gem::Specification.new do |s|
39
39
  "lib/datagrid/filters/enum_filter.rb",
40
40
  "lib/datagrid/filters/filter_eval.rb",
41
41
  "lib/datagrid/filters/integer_filter.rb",
42
+ "lib/datagrid/filters/string_filter.rb",
42
43
  "lib/datagrid/form_builder.rb",
43
44
  "lib/datagrid/helper.rb",
44
45
  "lib/datagrid/rspec.rb",
@@ -56,11 +57,10 @@ Gem::Specification.new do |s|
56
57
  s.homepage = %q{http://github.com/bogdan/datagrid}
57
58
  s.licenses = ["MIT"]
58
59
  s.require_paths = ["lib"]
59
- s.rubygems_version = %q{1.3.7}
60
+ s.rubygems_version = %q{1.6.2}
60
61
  s.summary = %q{Ruby gem to create datagrids}
61
62
 
62
63
  if s.respond_to? :specification_version then
63
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
64
64
  s.specification_version = 3
65
65
 
66
66
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -29,6 +29,7 @@ module Datagrid
29
29
  end # InstanceMethods
30
30
 
31
31
  class ConfigurationError < StandardError; end
32
+ class ArgumentError < StandardError; end
32
33
 
33
34
 
34
35
  end
@@ -14,7 +14,24 @@ module Datagrid
14
14
 
15
15
  include Datagrid::Core
16
16
 
17
- datagrid_attribute :order
17
+ datagrid_attribute :order do |value|
18
+ unless value.blank?
19
+ value = value.to_sym
20
+ column = column_by_name(value)
21
+ unless column
22
+ order_unsupported(value, "no column #{value} in #{self.class}")
23
+ end
24
+ unless column.order
25
+ order_unsupported(
26
+ name, "#{self.class}##{name} don't support order"
27
+ )
28
+ end
29
+ value
30
+ else
31
+ nil
32
+ end
33
+
34
+ end
18
35
  datagrid_attribute :descending do |value|
19
36
  Datagrid::Utils.booleanize(value)
20
37
  end
@@ -30,69 +47,6 @@ module Datagrid
30
47
  @columns ||= []
31
48
  end
32
49
 
33
- # Defines column that will be used to display data.
34
- #
35
- # Example:
36
- #
37
- # class UserGrid
38
- # include Datagrid
39
- #
40
- # scope do
41
- # User.order("users.created_at desc").includes(:group)
42
- # end
43
- #
44
- # column(:name)
45
- # column(:group, :order => "groups.name")
46
- # self.group.name
47
- # end
48
- # column(:active, :header => "Activated") do |user|
49
- # !user.disabled
50
- # end
51
- #
52
- # end
53
- #
54
- # Each column will be used to generate data.
55
- # In order to create grid that display all users:
56
- #
57
- # grid = UserGrid.new
58
- # grid.rows
59
- # grid.header # => ["Group", "Name", "Disabled"]
60
- # grid.rows # => [
61
- # # ["Steve", "Spammers", true],
62
- # # [ "John", "Spoilers", true],
63
- # # ["Berry", "Good people", false]
64
- # # ]
65
- # grid.data # => Header & Rows
66
- #
67
- # = Column value
68
- #
69
- # Column value can be defined by passing a block to <tt>#column</tt> method.
70
- # If no block given column it is generated automatically by sending column name method to model.
71
- # The block could have zero arguments(<tt>instance_eval</tt>) or one argument that is model object.
72
- #
73
- # = Column options
74
- #
75
- # The following options can be passed to column definition:
76
- #
77
- # * <tt>:order</tt> - an order SQL that should be used to sort by this column.
78
- # Default: report column name if there is database column with this name.
79
- # * <tt>:order_desc</tt> - descending order expression from this column. Default: "#{order} desc".
80
- #
81
- # TODO: frontend options description
82
- #
83
- # = Columns order
84
- #
85
- # Each column supports <tt>:order</tt> option that is used to specify SQL to sort data by the given column.
86
- # In order to specify order the following attributes are used:
87
- #
88
- # * <tt>:order</tt> - column name to sort with as <tt>Symbol</tt>. Default: nil.
89
- # * <tt>:descending</tt> - if true descending suffix is added to specified order. Default: false.
90
- #
91
- # Example:
92
- #
93
- # grid = UserGrid.new(:order => :group, :descending => true)
94
- # grid.assets # => Return assets ordered by :group column descending
95
- #
96
50
  def column(name, options = {}, &block)
97
51
  check_scope_defined!("Scope should be defined before columns")
98
52
  block ||= lambda do |model|
@@ -101,25 +55,36 @@ module Datagrid
101
55
  self.columns << Datagrid::Columns::Column.new(self, name, options, &block)
102
56
  end
103
57
 
58
+ def order_unsupported(name, reason)
59
+ raise Datagrid::OrderUnsupported, "Can not sort #{self.inspect} by ##{name}: #{reason}"
60
+ end
104
61
 
62
+ def column_by_name(name)
63
+ self.columns.find do |col|
64
+ col.name.to_sym == name.to_sym
65
+ end
66
+ end
105
67
  end # ClassMethods
106
68
 
107
69
  module InstanceMethods
108
70
 
71
+ # Returns <tt>Array</tt> of human readable column names. See also "Localization" section
109
72
  def header
110
73
  self.class.columns.map(&:header)
111
74
  end
112
75
 
76
+ # Returns <tt>Array</tt> column values for given asset
113
77
  def row_for(asset)
114
78
  self.class.columns.map do |column|
115
- column.value(asset)
79
+ column.value(asset, self)
116
80
  end
117
81
  end
118
82
 
83
+ # Returns <tt>Hash</tt> where keys are column names and values are column values for the given asset
119
84
  def hash_for(asset)
120
85
  result = {}
121
86
  self.class.columns.each do |column|
122
- result[column.name] = column.value(asset)
87
+ result[column.name] = column.value(asset, self)
123
88
  end
124
89
  result
125
90
  end
@@ -144,15 +109,20 @@ module Datagrid
144
109
  result = super
145
110
  if self.order
146
111
  column = column_by_name(self.order)
147
- raise Datagrid::OrderUnsupported, "Can not sort #{self.inspect} by #{name.inspect}" unless column
148
112
  result = result.order(self.descending ? column.desc_order : column.order)
149
113
  end
150
114
  result
151
115
  end
152
116
 
153
117
  def to_csv(options = {})
154
- require "fastercsv"
155
- FasterCSV.generate(
118
+ klass = if RUBY_VERSION >= "1.9"
119
+ require 'csv'
120
+ CSV
121
+ else
122
+ require "fastercsv"
123
+ FasterCSV
124
+ end
125
+ klass.generate(
156
126
  {:headers => self.header, :write_headers => true}.merge(options)
157
127
  ) do |csv|
158
128
  self.rows.each do |row|
@@ -166,9 +136,7 @@ module Datagrid
166
136
  end
167
137
 
168
138
  def column_by_name(name)
169
- self.columns.find do |col|
170
- col.name.to_sym == name.to_sym
171
- end
139
+ self.class.column_by_name(name)
172
140
  end
173
141
 
174
142
  end # InstanceMethods
@@ -10,15 +10,17 @@ class Datagrid::Columns::Column
10
10
  self.block = block
11
11
  end
12
12
 
13
- def value(object)
14
- value_for(object)
13
+ def value(model, report)
14
+ value_for(model, report)
15
15
  end
16
16
 
17
- def value_for(object)
17
+ def value_for(model, report)
18
18
  if self.block.arity == 1
19
- self.block.call(object)
19
+ self.block.call(model)
20
+ elsif self.block.arity == 2
21
+ self.block.call(model, report)
20
22
  else
21
- object.instance_eval(&self.block)
23
+ model.instance_eval(&self.block)
22
24
  end
23
25
  end
24
26
 
@@ -32,7 +34,7 @@ class Datagrid::Columns::Column
32
34
 
33
35
  def header
34
36
  self.options[:header] ||
35
- I18n.translate(self.name, :scope => "reports.#{self.grid}.columns", :default => self.name.to_s.humanize )
37
+ I18n.translate(self.name, :scope => "reports.#{self.grid.param_name}.columns", :default => self.name.to_s.humanize )
36
38
  end
37
39
 
38
40
  def order
@@ -10,10 +10,11 @@ module Datagrid
10
10
  require "datagrid/filters/filter_eval"
11
11
  require "datagrid/filters/integer_filter"
12
12
  require "datagrid/filters/composite_filters"
13
+ require "datagrid/filters/string_filter"
13
14
 
14
15
  FILTER_TYPES = {
15
16
  :date => Filters::DateFilter,
16
- :string => Filters::DefaultFilter,
17
+ :string => Filters::StringFilter,
17
18
  :default => Filters::DefaultFilter,
18
19
  :eboolean => Filters::BooleanEnumFilter ,
19
20
  :boolean => Filters::BooleanFilter ,
@@ -45,62 +46,9 @@ module Datagrid
45
46
  end
46
47
 
47
48
 
48
- # Defines the accessible attribute that is used to filter
49
- # scope by the specified value with specified code.
50
- #
51
- # Example:
52
- #
53
- # class UserGrid
54
- # include Datagrid
55
- #
56
- # scope do
57
- # User.order("users.created_at desc")
58
- # end
59
- #
60
- # filter(:name)
61
- # filter(:posts_count, :integer) do |value|
62
- # self.where(["posts_count >= ?", value])
63
- # end
64
- #
65
- # end
66
- #
67
- # Each filter becomes grid attribute.
68
- # In order to create grid that display all users with name 'John' that have more than zero posts:
69
- #
70
- # grid = UserGrid.new(:posts_count => 1, :name => "John")
71
- # grid.assets # SELECT * FROM users WHERE users.posts_count > 1 AND name = 'John'
72
- #
73
- # Important! Take care about non-breaking the filter chain and force objects loading in filter.
74
- # The filter block should always return a <tt>ActiveRecord::Scope</tt> rather than <tt>Array</tt>
75
- #
76
- # = Default filter block
77
- #
78
- # If no block given filter is generated automatically as simple select by filter name from scope.
79
- #
80
- # = Filter types
81
- #
82
- # Filter does types conversion automatically.
83
- # The following filter types are supported:
84
- #
85
- # * <tt>:default</tt> (default) - leave value as is
86
- # * <tt>:date</tt> - converts value to date using date parser
87
- # * <tt>:enum</tt> - designed to be collection select. Additional options for easy form generation:
88
- # * <tt>:select</tt> (required) - collection of values to match against.
89
- # * <tt>:boolean</tt> - converts value to true or false depending on whether it looks truly or not
90
- # * <tt>:integer</tt> - converts given value to integer.
91
- # * <tt>:eboolean</tt> - subtype of enum filter that provides select of "Yes", "No" and "Any". Could be useful.
92
- #
93
- # = Default filter options
94
- #
95
- # Options that could be passed to any filter type:
96
- #
97
- # * <tt>:header</tt> - human readable name of the filter. Default: generated from the filter name.
98
- # * <tt>:default</tt> - default value of the filter. Default: nil.
99
- # * <tt>:multiple</tt> - if true multiple values can be assigned to this filter. Default: false.
100
- # * <tt>:allow_nil</tt> - determines if filter should be called if filter value is nil. Default: false.
101
- # * <tt>:allow_blank</tt> - determines if filter should be called if filter value is #blank?. Default: false.
102
- #
103
- def filter(attribute, type = :string, options = {}, &block)
49
+ def filter(attribute, *args, &block)
50
+ options = args.extract_options!
51
+ type = args.shift || :default
104
52
 
105
53
  klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
106
54
  raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
@@ -119,12 +67,8 @@ module Datagrid
119
67
  protected
120
68
  def default_filter(attribute)
121
69
  check_scope_defined!("Scope should be defined before filters")
122
- if self.scope.column_names.include?(attribute.to_s)
123
- lambda do |value|
124
- self.scoped(:conditions => {attribute => value})
125
- end
126
- else
127
- raise ConfigurationError, "Not able to generate default filter. No column '#{attribute}' in #{self.scope.table_name}."
70
+ lambda do |value|
71
+ self.scoped(:conditions => {attribute => value})
128
72
  end
129
73
  end
130
74
 
@@ -22,6 +22,9 @@ class Datagrid::Filters::BaseFilter
22
22
  end
23
23
 
24
24
  def format_values(value)
25
+ if !self.multiple && value.is_a?(Array)
26
+ raise Datagrid::ArgumentError, "#{grid.class}.#{name} filter can not accept Array argument. Use :multiple option."
27
+ end
25
28
  values = Array(value)
26
29
  values.map! do |value|
27
30
  self.format(value)
@@ -31,7 +34,7 @@ class Datagrid::Filters::BaseFilter
31
34
 
32
35
  def header
33
36
  options[:header] ||
34
- I18n.translate(self.name, :scope => "datagrid.#{grid.class.to_s.underscore.split("/").last}.filters", :default => self.name.to_s.humanize)
37
+ I18n.translate(self.name, :scope => "datagrid.#{grid.param_name}.filters", :default => self.name.to_s.humanize)
35
38
  end
36
39
 
37
40
  def default
@@ -5,7 +5,6 @@ class Datagrid::Filters::BooleanEnumFilter < Datagrid::Filters::EnumFilter
5
5
  VALUES = {YES => true, NO => false}
6
6
 
7
7
  def initialize(report, attribute, options = {}, &block)
8
- options[:allow_blank] = true unless options.has_key?(:allow_blank)
9
8
  options[:select] = VALUES.keys
10
9
  super(report, attribute, options, &block)
11
10
  end
@@ -0,0 +1,5 @@
1
+ class Datagrid::Filters::StringFilter < Datagrid::Filters::BaseFilter
2
+ def format(value)
3
+ value.to_s
4
+ end
5
+ end
@@ -36,11 +36,22 @@ module Datagrid
36
36
 
37
37
  def datagrid_enum_filter(attribute_or_filter, options = {})
38
38
  filter = get_filter(attribute_or_filter)
39
- select filter.name, filter.select || [], {:include_blank => filter.include_blank}, {:multiple => filter.multiple}.merge(options)
39
+ if !options.has_key?(:multiple) && filter.multiple
40
+ options[:multiple] = true
41
+ end
42
+ select filter.name, filter.select || [], {:include_blank => filter.include_blank}, options
40
43
  end
41
44
 
42
45
  def datagrid_integer_filter(attribute_or_filter, options = {})
43
- text_field get_attribute(attribute_or_filter), options
46
+ filter = get_filter(attribute_or_filter)
47
+ if filter.multiple && self.object[filter.name].blank?
48
+ options[:value] = ""
49
+ end
50
+ text_field filter.name, options
51
+ end
52
+
53
+ def datagrid_string_filter(attribute_or_filter, options = {})
54
+ datagrid_default_filter(attribute_or_filter, options)
44
55
  end
45
56
 
46
57
  def get_attribute(attribute_or_filter)
@@ -3,8 +3,8 @@ require "action_view"
3
3
  module Datagrid
4
4
  module Helper
5
5
 
6
- def datagrid_format_value(column, asset)
7
- value = column.value(asset)
6
+ def datagrid_format_value(report, column, asset)
7
+ value = column.value(asset, report)
8
8
  if column.options[:url]
9
9
  link_to(value, column.options[:url].call(asset))
10
10
  else
@@ -24,11 +24,10 @@ module Datagrid
24
24
  assets = report.assets
25
25
  paginate = options[:paginate]
26
26
  assets = assets.paginate(paginate) if paginate
27
- content = content_tag(:tr, datagrid_header(report, options)) + datagrid_rows(report.columns, assets, options)
27
+ content = content_tag(:tr, datagrid_header(report, options)) + datagrid_rows(report, assets, options)
28
28
  content_tag(:table, content, html)
29
29
  end
30
30
 
31
- protected
32
31
 
33
32
  def datagrid_header(grid, options = {})
34
33
  header = empty_string
@@ -43,12 +42,13 @@ module Datagrid
43
42
  header
44
43
  end
45
44
 
46
- def datagrid_rows(columns, assets, options)
45
+ def datagrid_rows(report, assets, options)
46
+ columns = report.columns
47
47
  result = assets.map do |asset|
48
48
  content = columns.map do |column|
49
- content_tag(:td, datagrid_format_value(column, asset))
49
+ content_tag(:td, datagrid_format_value(report, column, asset))
50
50
  end.join(empty_string)
51
- content_tag(:tr, _safe(content), :class => cycle("odd", "even"))
51
+ content_tag(:tr, _safe(content), :class => options[:cycle] && cycle(*options[:cycle]))
52
52
  end.join(empty_string)
53
53
  _safe(result)
54
54
  end
@@ -27,4 +27,39 @@ describe Datagrid::Columns do
27
27
  it "should support csv export" do
28
28
  subject.to_csv.should == "Group,Name\nPop,Star\n"
29
29
  end
30
+
31
+ it "should support columns with model and report arguments" do
32
+ report = test_report(:category => "foo") do
33
+ scope {Entry.order(:category)}
34
+ filter(:category) do |value|
35
+ where("category LIKE '%#{value}%'")
36
+ end
37
+
38
+ column(:exact_category) do |entry, report|
39
+ entry.category == report.category
40
+ end
41
+ end
42
+ Entry.create!(:category => "foo")
43
+ Entry.create!(:category => "foobar")
44
+ report.rows.first.first.should be_true
45
+ report.rows.last.first.should be_false
46
+ end
47
+
48
+
49
+ it "should raise error if ordered by not existing column" do
50
+ lambda {
51
+ test_report(:order => :hello)
52
+ }.should raise_error(Datagrid::OrderUnsupported)
53
+ end
54
+
55
+ it "should raise error if ordered by column without order" do
56
+ lambda {
57
+ test_report(:order => :category) do
58
+ filter(:category, :default, :order => false) do |value|
59
+ self
60
+ end
61
+ end
62
+ }.should raise_error(Datagrid::OrderUnsupported)
63
+ end
64
+
30
65
  end
@@ -8,5 +8,28 @@ describe Datagrid::Filters do
8
8
  filter(:created_at, :date, :default => proc { Date.today } )
9
9
  end.created_at.should == Date.today
10
10
  end
11
+
12
+ it "should not support array argument for not multiple filter" do
13
+ report = test_report do
14
+ scope {Entry}
15
+ filter(:group_id, :integer)
16
+ end
17
+ lambda {
18
+ report.group_id = [1,2]
19
+ }.should raise_error(Datagrid::ArgumentError)
20
+ end
21
+
22
+
23
+ it "should initialize report Scope table not exists" do
24
+ class ModelWithoutTable < ActiveRecord::Base; end
25
+ class TheReport
26
+ include Datagrid
27
+
28
+ scope {ModelWithoutTable}
29
+
30
+ filter(:name)
31
+ end
32
+
33
+ end
11
34
 
12
35
  end
@@ -36,7 +36,7 @@ describe Datagrid::FormBuilder do
36
36
  context "with enum filter type" do
37
37
  let(:_filter) { :category }
38
38
  it { should equal_to_dom(
39
- '<select class="category enum_filter" id="report_category" name="report[category][]"><option value=""></option>
39
+ '<select class="category enum_filter" id="report_category" name="report[category]"><option value=""></option>
40
40
  <option value="first">first</option>
41
41
  <option value="second">second</option></select>'
42
42
  )}
@@ -45,7 +45,7 @@ describe Datagrid::FormBuilder do
45
45
  grid.category = "first"
46
46
  end
47
47
  it { should equal_to_dom(
48
- '<select class="category enum_filter" id="report_category" name="report[category][]"><option value=""></option>
48
+ '<select class="category enum_filter" id="report_category" name="report[category]"><option value=""></option>
49
49
  <option value="first" selected="true">first</option>
50
50
  <option value="second">second</option></select>'
51
51
  )}
@@ -55,11 +55,39 @@ describe Datagrid::FormBuilder do
55
55
  context "with eboolean filter type" do
56
56
  let(:_filter) { :disabled }
57
57
  it { should equal_to_dom(
58
- '<select class="disabled boolean_enum_filter" id="report_disabled" name="report[disabled][]"><option value=""></option>
59
- <option value="NO">NO</option>
60
- <option value="YES">YES</option></select>'
58
+ '<select class="disabled boolean_enum_filter" id="report_disabled" name="report[disabled]"><option value=""></option>
59
+ <option value="YES">YES</option>
60
+ <option value="NO">NO</option></select>'
61
61
  )}
62
62
  end
63
+ context "with string filter" do
64
+ let(:grid) do
65
+ test_report do
66
+ scope {Entry}
67
+ filter(:name, :string)
68
+ end
69
+ end
70
+
71
+ let(:_filter) { :name }
72
+
73
+ it {should equal_to_dom('<input class="name string_filter" id="report_name" name="report[name]" size="30" type="text">')}
74
+ end
75
+
76
+ context "with non multiple filter" do
77
+ let(:grid) do
78
+ test_report do
79
+ scope {Entry}
80
+ filter(
81
+ :name, :enum,
82
+ :include_blank => false,
83
+ :multiple => false,
84
+ :select => []
85
+ )
86
+ end
87
+ end
88
+ let(:_filter) { :name }
89
+ it {should equal_to_dom('<select class="name enum_filter" id="report_name" name="report[name]"></select>')}
90
+ end
63
91
  end
64
92
 
65
93
  describe ".datagrid_label" do
@@ -69,6 +97,9 @@ describe Datagrid::FormBuilder do
69
97
  )
70
98
  end
71
99
  end
100
+
101
+
102
+
72
103
  end
73
104
 
74
105
 
@@ -34,12 +34,21 @@ describe Datagrid::Helper do
34
34
  </th>
35
35
  </tr>
36
36
 
37
- <tr class="odd">
37
+ <tr>
38
38
  <td>Pop</td>
39
39
  <td>Star</td>
40
40
  </tr>
41
41
  </table>')
42
42
  end
43
+
44
+ it "should support cycle option" do
45
+ subject.datagrid_rows(grid, [entry], :cycle => ["odd", "even"]).should equal_to_dom(
46
+ '<tr class="odd">
47
+ <td>Pop</td>
48
+ <td>Star</td>
49
+ </tr>'
50
+ )
51
+ end
43
52
  end
44
53
 
45
54
 
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
  require "datagrid/rspec"
3
3
 
4
4
 
5
- describe Datagrid do
5
+ describe SimpleReport do
6
6
 
7
- #it_should_behave_like 'Datagrid'
7
+ it_should_behave_like 'Datagrid'
8
8
 
9
9
  let(:group) { Group.create!(:name => "Pop") }
10
10
 
@@ -10,11 +10,14 @@ end
10
10
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
11
  $LOAD_PATH.unshift(File.dirname(__FILE__))
12
12
 
13
- require 'rspec'
14
13
  require "active_record"
15
14
  require "will_paginate"
16
15
  require 'datagrid'
17
- require 'ruby-debug'
16
+ begin
17
+ #require 'ruby-debug'
18
+ rescue
19
+ end
20
+ require 'rspec'
18
21
 
19
22
 
20
23
  RSpec.configure do |config|
@@ -16,7 +16,7 @@ class IncludeDom
16
16
 
17
17
  def matches?(text)
18
18
  @matcher = Nokogiri::HTML::DocumentFragment.parse(text).to_s
19
- @matcher.include?(@expectation)
19
+ @matcher == @expectation
20
20
  end
21
21
 
22
22
  def failure_message
@@ -17,8 +17,8 @@ ActiveRecord::Schema.define(:version => 1) do
17
17
  t.integer :group_id
18
18
  t.string :name
19
19
  t.string :category
20
- t.boolean :disabled, :null => false, :default => nil
21
- t.boolean :confirmed, :null => false, :default => nil
20
+ t.boolean :disabled, :null => false, :default => false
21
+ t.boolean :confirmed, :null => false, :default => false
22
22
  t.timestamps
23
23
  end
24
24
 
@@ -1,12 +1,14 @@
1
1
 
2
2
 
3
- def test_report(&block)
3
+ def test_report(attributes = {}, &block)
4
4
  klass = Class.new
5
5
  klass.class_eval do
6
6
  include Datagrid
7
7
  end
8
- klass.class_eval(&block)
9
- klass.new
8
+ if block
9
+ klass.class_eval(&block)
10
+ end
11
+ klass.new(attributes)
10
12
  end
11
13
 
12
14
  class SimpleReport
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datagrid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 2
9
- - 0
10
- version: 0.2.0
4
+ prerelease:
5
+ version: 0.3.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Bogdan Gusiev
@@ -15,187 +10,141 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-06-22 00:00:00 +03:00
13
+ date: 2011-07-01 00:00:00 +03:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
22
- version_requirements: &id001 !ruby/object:Gem::Requirement
17
+ name: rails
18
+ requirement: &id001 !ruby/object:Gem::Requirement
23
19
  none: false
24
20
  requirements:
25
21
  - - ">="
26
22
  - !ruby/object:Gem::Version
27
- hash: 3
28
- segments:
29
- - 0
30
23
  version: "0"
31
- requirement: *id001
32
24
  type: :runtime
33
- name: rails
34
25
  prerelease: false
26
+ version_requirements: *id001
35
27
  - !ruby/object:Gem::Dependency
36
- version_requirements: &id002 !ruby/object:Gem::Requirement
28
+ name: rake
29
+ requirement: &id002 !ruby/object:Gem::Requirement
37
30
  none: false
38
31
  requirements:
39
32
  - - "="
40
33
  - !ruby/object:Gem::Version
41
- hash: 49
42
- segments:
43
- - 0
44
- - 8
45
- - 7
46
34
  version: 0.8.7
47
- requirement: *id002
48
35
  type: :development
49
- name: rake
50
36
  prerelease: false
37
+ version_requirements: *id002
51
38
  - !ruby/object:Gem::Dependency
52
- version_requirements: &id003 !ruby/object:Gem::Requirement
39
+ name: mocha
40
+ requirement: &id003 !ruby/object:Gem::Requirement
53
41
  none: false
54
42
  requirements:
55
43
  - - ">="
56
44
  - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
45
  version: "0"
61
- requirement: *id003
62
46
  type: :development
63
- name: mocha
64
47
  prerelease: false
48
+ version_requirements: *id003
65
49
  - !ruby/object:Gem::Dependency
66
- version_requirements: &id004 !ruby/object:Gem::Requirement
50
+ name: rspec
51
+ requirement: &id004 !ruby/object:Gem::Requirement
67
52
  none: false
68
53
  requirements:
69
54
  - - "="
70
55
  - !ruby/object:Gem::Version
71
- hash: 23
72
- segments:
73
- - 2
74
- - 6
75
- - 0
76
56
  version: 2.6.0
77
- requirement: *id004
78
57
  type: :development
79
- name: rspec
80
58
  prerelease: false
59
+ version_requirements: *id004
81
60
  - !ruby/object:Gem::Dependency
82
- version_requirements: &id005 !ruby/object:Gem::Requirement
61
+ name: bundler
62
+ requirement: &id005 !ruby/object:Gem::Requirement
83
63
  none: false
84
64
  requirements:
85
65
  - - ~>
86
66
  - !ruby/object:Gem::Version
87
- hash: 23
88
- segments:
89
- - 1
90
- - 0
91
- - 0
92
67
  version: 1.0.0
93
- requirement: *id005
94
68
  type: :development
95
- name: bundler
96
69
  prerelease: false
70
+ version_requirements: *id005
97
71
  - !ruby/object:Gem::Dependency
98
- version_requirements: &id006 !ruby/object:Gem::Requirement
72
+ name: jeweler
73
+ requirement: &id006 !ruby/object:Gem::Requirement
99
74
  none: false
100
75
  requirements:
101
76
  - - ~>
102
77
  - !ruby/object:Gem::Version
103
- hash: 15
104
- segments:
105
- - 1
106
- - 6
107
- - 0
108
78
  version: 1.6.0
109
- requirement: *id006
110
79
  type: :development
111
- name: jeweler
112
80
  prerelease: false
81
+ version_requirements: *id006
113
82
  - !ruby/object:Gem::Dependency
114
- version_requirements: &id007 !ruby/object:Gem::Requirement
83
+ name: rcov
84
+ requirement: &id007 !ruby/object:Gem::Requirement
115
85
  none: false
116
86
  requirements:
117
87
  - - ">="
118
88
  - !ruby/object:Gem::Version
119
- hash: 3
120
- segments:
121
- - 0
122
89
  version: "0"
123
- requirement: *id007
124
90
  type: :development
125
- name: rcov
126
91
  prerelease: false
92
+ version_requirements: *id007
127
93
  - !ruby/object:Gem::Dependency
128
- version_requirements: &id008 !ruby/object:Gem::Requirement
94
+ name: ruby-debug
95
+ requirement: &id008 !ruby/object:Gem::Requirement
129
96
  none: false
130
97
  requirements:
131
98
  - - ">="
132
99
  - !ruby/object:Gem::Version
133
- hash: 3
134
- segments:
135
- - 0
136
100
  version: "0"
137
- requirement: *id008
138
101
  type: :development
139
- name: ruby-debug
140
102
  prerelease: false
103
+ version_requirements: *id008
141
104
  - !ruby/object:Gem::Dependency
142
- version_requirements: &id009 !ruby/object:Gem::Requirement
105
+ name: sqlite3-ruby
106
+ requirement: &id009 !ruby/object:Gem::Requirement
143
107
  none: false
144
108
  requirements:
145
109
  - - ">="
146
110
  - !ruby/object:Gem::Version
147
- hash: 3
148
- segments:
149
- - 0
150
111
  version: "0"
151
- requirement: *id009
152
112
  type: :development
153
- name: sqlite3-ruby
154
113
  prerelease: false
114
+ version_requirements: *id009
155
115
  - !ruby/object:Gem::Dependency
156
- version_requirements: &id010 !ruby/object:Gem::Requirement
116
+ name: fastercsv
117
+ requirement: &id010 !ruby/object:Gem::Requirement
157
118
  none: false
158
119
  requirements:
159
120
  - - ">="
160
121
  - !ruby/object:Gem::Version
161
- hash: 3
162
- segments:
163
- - 0
164
122
  version: "0"
165
- requirement: *id010
166
123
  type: :development
167
- name: fastercsv
168
124
  prerelease: false
125
+ version_requirements: *id010
169
126
  - !ruby/object:Gem::Dependency
170
- version_requirements: &id011 !ruby/object:Gem::Requirement
127
+ name: nokogiri
128
+ requirement: &id011 !ruby/object:Gem::Requirement
171
129
  none: false
172
130
  requirements:
173
131
  - - ">="
174
132
  - !ruby/object:Gem::Version
175
- hash: 3
176
- segments:
177
- - 0
178
133
  version: "0"
179
- requirement: *id011
180
134
  type: :development
181
- name: nokogiri
182
135
  prerelease: false
136
+ version_requirements: *id011
183
137
  - !ruby/object:Gem::Dependency
184
- version_requirements: &id012 !ruby/object:Gem::Requirement
138
+ name: will_paginate
139
+ requirement: &id012 !ruby/object:Gem::Requirement
185
140
  none: false
186
141
  requirements:
187
142
  - - "="
188
143
  - !ruby/object:Gem::Version
189
- hash: 29
190
- segments:
191
- - 2
192
- - 3
193
- - 15
194
144
  version: 2.3.15
195
- requirement: *id012
196
145
  type: :development
197
- name: will_paginate
198
146
  prerelease: false
147
+ version_requirements: *id012
199
148
  description: This allows you to easily build datagrid aka data tables with sortable columns and filters
200
149
  email: agresso@gmail.com
201
150
  executables: []
@@ -228,6 +177,7 @@ files:
228
177
  - lib/datagrid/filters/enum_filter.rb
229
178
  - lib/datagrid/filters/filter_eval.rb
230
179
  - lib/datagrid/filters/integer_filter.rb
180
+ - lib/datagrid/filters/string_filter.rb
231
181
  - lib/datagrid/form_builder.rb
232
182
  - lib/datagrid/helper.rb
233
183
  - lib/datagrid/rspec.rb
@@ -255,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
205
  requirements:
256
206
  - - ">="
257
207
  - !ruby/object:Gem::Version
258
- hash: 3
208
+ hash: -315143401371934304
259
209
  segments:
260
210
  - 0
261
211
  version: "0"
@@ -264,14 +214,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
214
  requirements:
265
215
  - - ">="
266
216
  - !ruby/object:Gem::Version
267
- hash: 3
268
- segments:
269
- - 0
270
217
  version: "0"
271
218
  requirements: []
272
219
 
273
220
  rubyforge_project:
274
- rubygems_version: 1.3.7
221
+ rubygems_version: 1.6.2
275
222
  signing_key:
276
223
  specification_version: 3
277
224
  summary: Ruby gem to create datagrids