page_record 0.4.0 → 0.5.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.
Files changed (41) hide show
  1. data/.rubocop.yml +13 -0
  2. data/CHANGES.md +5 -0
  3. data/Gemfile.lock +46 -14
  4. data/Guardfile +24 -0
  5. data/README.md +27 -1
  6. data/bin/autospec +16 -0
  7. data/bin/guard +16 -0
  8. data/bin/rake +16 -0
  9. data/bin/rspec +16 -0
  10. data/lib/page_record/attribute_accessors.rb +57 -54
  11. data/lib/page_record/base.rb +27 -22
  12. data/lib/page_record/class_actions.rb +47 -50
  13. data/lib/page_record/class_methods.rb +252 -261
  14. data/lib/page_record/errors.rb +81 -82
  15. data/lib/page_record/finders.rb +129 -131
  16. data/lib/page_record/form_builder.rb +4 -4
  17. data/lib/page_record/formtastic.rb +20 -9
  18. data/lib/page_record/helpers.rb +192 -131
  19. data/lib/page_record/inspector.rb +36 -0
  20. data/lib/page_record/instance_actions.rb +44 -46
  21. data/lib/page_record/rspec.rb +1 -1
  22. data/lib/page_record/validation.rb +46 -0
  23. data/lib/page_record/version.rb +1 -1
  24. data/lib/page_record.rb +13 -15
  25. data/page_record.gemspec +4 -1
  26. data/spec/.rubocop.yml +4 -0
  27. data/spec/helpers_spec.rb +109 -100
  28. data/spec/inspector_spec.rb +70 -0
  29. data/spec/page_record_spec.rb +357 -388
  30. data/spec/spec_helper.rb +1 -3
  31. data/spec/support/shared_contexts.rb +24 -2
  32. data/spec/support/shared_examples.rb +41 -45
  33. data/spec/support/team.rb +4 -4
  34. data/spec/support/test_app.rb +10 -13
  35. data/spec/support/views/page-with-1-error.erb +5 -0
  36. data/spec/support/views/page-with-2-errors-on-different-attributes.erb +9 -0
  37. data/spec/support/views/page-with-2-errors-on-same-attribute.erb +6 -0
  38. data/spec/support/views/page-without-errors.erb +4 -0
  39. data/spec/validation_spec.rb +142 -0
  40. data/tmp/rspec_guard_result +1 -0
  41. metadata +80 -5
@@ -2,118 +2,177 @@ module PageRecord
2
2
 
3
3
  module Helpers
4
4
 
5
- ##
6
- #
7
- # returns a hash containing the record-type and the id. The id is based on the type. For example when
8
- # you specify `:team` as the type, it will search for the `@type` instance variable.
9
- #
10
- # example:
11
- #
12
- # ```ruby
13
- # <%= form_for(@team, html:form_record_for(:team)) do |f| %>
14
- # <% end %>
15
- # ```
16
- # this returns the follwing HTML:
17
- #
18
- # ```html
19
- # <form accept-charset="UTF-8" action="/teams/2" class="edit_team" data-team-id="2" id="edit_team_2" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value=""><input name="_method" type="hidden" value="patch"><input name="authenticity_token" type="hidden" value="QXIbPXH65Ek+8i0j2R8akdHX2WXLo2MuDFuUVL8CQpY="></div>
20
- # </form>
21
- # ```
22
- #
23
- # @param type Symbol identifying the type of record and the variable to use
24
- # @param var the variable to use. This is optional
25
- #
26
- # @return Hash
27
- #
28
- #
29
- def form_record_for(type, var=nil)
5
+ ##
6
+ #
7
+ # returns a hash containing the record-type and the id. The id is based on the type. For example when
8
+ # you specify `:team` as the type, it will search for the `@type` instance variable.
9
+ #
10
+ # example:
11
+ #
12
+ # ```ruby
13
+ # <%= form_for(@team, html:form_record_for(:team)) do |f| %>
14
+ # <% end %>
15
+ # ```
16
+ # this returns the follwing HTML:
17
+ #
18
+ # ```html
19
+ # <form accept-charset="UTF-8" action="/teams/2" class="edit_team" data-team-id="2" id="edit_team_2" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value=""><input name="_method" type="hidden" value="patch"><input name="authenticity_token" type="hidden" value="QXIbPXH65Ek+8i0j2R8akdHX2WXLo2MuDFuUVL8CQpY="></div>
20
+ # </form>
21
+ # ```
22
+ #
23
+ # @param type Symbol identifying the type of record and the variable to use
24
+ # @param var the variable to use. This is optional
25
+ #
26
+ # @return Hash
27
+ #
28
+ #
29
+ def form_record_for(type, var = nil)
30
30
  if var
31
31
  id = var.id
32
32
  else
33
33
  id = instance_eval("@#{type}.id")
34
34
  end
35
35
  id ||= 'new'
36
- Hash["data-#{type}-id",id]
36
+ Hash["data-#{type}-id", id]
37
37
  end
38
38
 
39
- ##
40
- #
41
- # Returns a hash containing the attribute name. This can be used as html options in rails helpers
42
- #
43
- # example in a form builder block:
44
- #
45
- # ```ruby
46
- #<%= f.text_field :name, attribute_for(:name) %>
47
- # ```
48
- #
49
- # this returns the follwing HTML:
50
- #
51
- # ```html
52
- # <input data-attribute-for="name" id="team_name" name="team[name]" type="text">
53
- # ```
54
- #
55
- # @param name Symbol or String identifying the name
56
- #
57
- # @return Hash
58
- #
59
- #
39
+ ##
40
+ #
41
+ # returns a string containing the record-type and the id. The id is based on the type. For example when
42
+ # you specify `:team` as the type, it will search for the `type` instance variable.
43
+ #
44
+ # example:
45
+ #
46
+ # ```ruby
47
+ # <tr <%= record_for(:team)%>>
48
+ # ```
49
+ # this returns the follwing HTML:
50
+ #
51
+ # ```html
52
+ # <tr data-team-id="2">
53
+ # ```
54
+ #
55
+ # @param type Symbol identifying the type of record and the variable to use
56
+ # @param var the variable to use. This is optional
57
+ #
58
+ # @return Hash
59
+ #
60
+ #
61
+ def record_for(record, type = nil)
62
+ unless type
63
+ type = record.class.to_s.downcase
64
+ end
65
+ "data-#{type}-id=#{record.id}"
66
+ end
67
+
68
+ ##
69
+ #
70
+ # Returns a hash containing the attribute name. This can be used as html options in rails helpers
71
+ #
72
+ # example in a form builder block:
73
+ #
74
+ # ```ruby
75
+ # <%= f.text_field :name, attribute_for(:name) %>
76
+ # ```
77
+ #
78
+ # this returns the follwing HTML:
79
+ #
80
+ # ```html
81
+ # <input data-attribute-for="name" id="team_name" name="team[name]" type="text">
82
+ # ```
83
+ #
84
+ # @param name Symbol or String identifying the name
85
+ #
86
+ # @return Hash
87
+ #
88
+ #
60
89
  def attribute_for(name)
61
- Hash["data-attribute-for",name]
90
+ Hash['data-attribute-for', name]
62
91
  end
63
92
 
64
- ##
65
- #
66
- # Returns a hash containing the action name. This can be used as html options in rails helpers
67
- #
68
- # example in a form builder block:
69
- #
70
- # ```ruby
71
- # <%= f.submit "Submit", action_for(:save)%>
72
- # ```
73
- #
74
- # this returns the follwing HTML:
75
- #
76
- # ```html
77
- # <input data-action-for="submit" name="commit" type="submit" value="Submit">
78
- # ```
79
- #
80
- # @param name Symbol or String identifying the action name
81
- #
82
- # @return Hash
83
- #
84
- #
93
+ ##
94
+ #
95
+ # Returns a hash containing the action name. This can be used as html options in rails helpers
96
+ #
97
+ # example in a form builder block:
98
+ #
99
+ # ```ruby
100
+ # <%= f.submit "Submit", action_for(:save)%>
101
+ # ```
102
+ #
103
+ # this returns the follwing HTML:
104
+ #
105
+ # ```html
106
+ # <input data-action-for="submit" name="commit" type="submit" value="Submit">
107
+ # ```
108
+ #
109
+ # @param name Symbol or String identifying the action name
110
+ #
111
+ # @return Hash
112
+ #
113
+ #
85
114
  def action_for(name)
86
- Hash["data-action-for",name]
115
+ name = name.to_s
116
+ name = 'save' if name == 'submit'
117
+ Hash['data-action-for', name]
87
118
  end
88
119
 
89
- ##
90
- #
91
- # Writes a tag containing the specified PageRecord attribute
92
- #
93
- # example:
94
- #
95
- # ```ruby
96
- # <% @teams.each do |team| %>
97
- # <tr>
98
- # <%= attribute_tag_for(:td, :name) { team.name} %>
99
- # <%= attribute_tag_for(:td, :competition) { team.competition} %>
100
- # <%= attribute_tag_for(:td, :point) { team.point} %>
101
- # <%= attribute_tag_for(:td, :ranking) { team.ranking} %>
102
- # <td><%= link_to 'Show', team, action_for(:show) %></td>
103
- # <td><%= link_to 'Edit', edit_team_path(team), action_for(:edit) %></td>
104
- # <td><%= link_to 'Destroy', team, {method: :delete, data: { confirm: 'Are you sure?' }}.merge(action_for(:destroy)) %></td>
105
- # </tr>
106
- # ```
107
- #
108
- # the first `attribute_tag_for` lines returns the follwing HTML:
109
- #
110
- # ```html
111
- #<td data-attribute-for="name">aa</td>
112
- # ```
113
- #
114
- #
120
+
121
+ ##
122
+ #
123
+ # Returns a hash containing the error name. This can be used as html options in rails helpers
124
+ #
125
+ # example:
126
+ #
127
+ # TODO: Make an example
128
+ #
129
+ #
130
+ # this returns the follwing HTML:
131
+ #
132
+ # ```html
133
+ # <div data-error-for="name">can't be blank</div>
134
+ # ```
135
+ #
136
+ # @param name Symbol or String identifying the name
137
+ #
138
+ # @return Hash
139
+ #
140
+ #
141
+ def error_for(name)
142
+ Hash['data-error-for', name]
143
+ end
144
+
145
+
146
+
147
+ ##
148
+ #
149
+ # Writes a tag containing the specified PageRecord attribute
150
+ #
151
+ # example:
152
+ #
153
+ # ```ruby
154
+ # <% @teams.each do |team| %>
155
+ # <tr>
156
+ # <%= attribute_tag_for(:td, :name) { team.name} %>
157
+ # <%= attribute_tag_for(:td, :competition) { team.competition} %>
158
+ # <%= attribute_tag_for(:td, :point) { team.point} %>
159
+ # <%= attribute_tag_for(:td, :ranking) { team.ranking} %>
160
+ # <td><%= link_to 'Show', team, action_for(:show) %></td>
161
+ # <td><%= link_to 'Edit', edit_team_path(team), action_for(:edit) %></td>
162
+ # <td><%= link_to 'Destroy', team, {method: :delete, data: { confirm: 'Are you sure?' }}.merge(action_for(:destroy)) %></td>
163
+ # </tr>
164
+ # ```
165
+ #
166
+ # the first `attribute_tag_for` lines returns the follwing HTML:
167
+ #
168
+ # ```html
169
+ # <td data-attribute-for="name">aa</td>
170
+ # ```
171
+ #
172
+ #
173
+ # rubocop:disable ParameterLists
115
174
  def attribute_tag_for(name, attribute, content_or_options_with_block = nil, options = nil, escape = true, &block)
116
- options||= options ? options << {'data-attribute-for' => attribute} :{'data-attribute-for' => attribute}
175
+ options ||= options ? options << { 'data-attribute-for' => attribute } : { 'data-attribute-for' => attribute }
117
176
  if block_given?
118
177
  options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
119
178
  content_tag_string(name, capture(&block), options, escape)
@@ -121,57 +180,59 @@ module PageRecord
121
180
  content_tag_string(name, content_or_options_with_block, options, escape)
122
181
  end
123
182
  end
183
+ # rubocop:enable ParameterLists
124
184
 
125
185
  alias_method :atf, :attribute_tag_for
126
186
 
127
-
128
- ##
129
- #
130
- # build a form that automagicaly identifies a form as a PageRecord recognisable form
131
- # The form is identified by the id of the given record or `new` if the record is new.
132
- #
133
- # All the elements in the form are labeled according to there field name. And thus easy
134
- # recognisable by PageRecord
135
- #
136
- # example:
137
- #
138
- # ```ruby
139
- # <%= record_form_for(@team) do |f| %>
140
- # <div class="field" >
141
- # <%= f.label :name %><br>
142
- # <%= f.text_field :name %>
143
- # </div>
144
- # <div class="field"%>
145
- # <%= f.label :competition %><br>
146
- # <%= f.text_field :competition%>
147
- # </div>
148
- # <div class="actions">
149
- # <%= f.submit "Submit"%>
150
- # </div>
151
- # <% end %>
152
- # ```
153
- # @see
154
- #
155
- # @return formBuilder object
156
- #
157
- #
187
+ ##
188
+ #
189
+ # build a form that automagicaly identifies a form as a PageRecord recognisable form
190
+ # The form is identified by the id of the given record or `new` if the record is new.
191
+ #
192
+ # All the elements in the form are labeled according to there field name. And thus easy
193
+ # recognisable by PageRecord
194
+ #
195
+ # example:
196
+ #
197
+ # ```ruby
198
+ # <%= record_form_for(@team) do |f| %>
199
+ # <div class="field" >
200
+ # <%= f.label :name %><br>
201
+ # <%= f.text_field :name %>
202
+ # </div>
203
+ # <div class="field"%>
204
+ # <%= f.label :competition %><br>
205
+ # <%= f.text_field :competition%>
206
+ # </div>
207
+ # <div class="actions">
208
+ # <%= f.submit "Submit"%>
209
+ # </div>
210
+ # <% end %>
211
+ # ```
212
+ # @see
213
+ #
214
+ # @return formBuilder object
215
+ #
216
+ #
158
217
  def record_form_for(record, options = {}, &block)
159
218
  case record
160
219
  when String, Symbol
161
220
  object_name = record
162
221
  else
163
222
  object = record.is_a?(Array) ? record.last : record
164
- raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
223
+ raise ArgumentError, 'First argument in form cannot contain nil or be empty' unless object
165
224
  object_name = options[:as] || model_name_from_record_or_class(object).param_key
166
225
  end
167
- options = options.merge(html:form_record_for(object_name), builder:PageRecord::FormBuilder)
226
+ options = options.merge(html: form_record_for(object_name), builder: PageRecord::FormBuilder)
168
227
  form_for(record, options, &block)
169
228
  end
170
229
  end
171
230
 
172
231
  end
173
232
 
233
+ # rubocop:disable HandleExceptions
174
234
  begin
175
- ActionView::Base.send :include, PageRecord::Helpers
235
+ ActionView::Base.send :include, PageRecord::Helpers
176
236
  rescue NameError
177
237
  end
238
+ # rubocop:enable HandleExceptions
@@ -0,0 +1,36 @@
1
+ module PageRecord
2
+
3
+ module Inspector
4
+
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ def inspect
11
+ attributes = Hash.new
12
+ self.class.attributes.each do | attribute|
13
+ begin
14
+ attributes[attribute] = self.send(attribute)
15
+ rescue AttributeNotFound
16
+ attributes[attribute] = '--not found on page--'
17
+ end
18
+ end
19
+ attributes
20
+ end
21
+
22
+
23
+ module ClassMethods
24
+ def inspect
25
+ {
26
+ type: self.type,
27
+ host_class: self.host_class,
28
+ selector: self.selector,
29
+ filter: self.filter,
30
+ attributes: self.attributes,
31
+ }
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -1,52 +1,50 @@
1
1
  module PageRecord
2
- class Base
2
+ class Base
3
3
 
4
- ##
5
- # This is the implementation of the record action routine. It has two variants.
6
- # it has a `?` variant and a `normal` variant.
7
- #
8
- # normal variant:
9
- # It checks the page for a data-action-for='action' tag somewhere on the page.
10
- # If it finds it, it clicks it.
11
- #
12
- # `?` variant:
13
- # It checks the page for a data-action-for='action' tag somewhere on the page.
14
- # If it finds it, returns the Capybara element.
15
- #
16
- # @param action [Symbol] this is the name of the action
17
- #
18
- # @return [Capybara::Result]
19
- #
20
- # @raise [PageRecord::MultipleRecords] when there are more actions with
21
- # this name on the page
22
- #
23
- def method_missing(action)
24
- raw_action = /(.*)\?/.match(action)
25
- begin
26
- if raw_action
27
- action_for?(raw_action[1])
28
- else
29
- action_for(action)
30
- end
31
- rescue Capybara::ElementNotFound
32
- super
33
- end
34
- end
4
+ ##
5
+ # This is the implementation of the record action routine. It has two variants.
6
+ # it has a `?` variant and a `normal` variant.
7
+ #
8
+ # normal variant:
9
+ # It checks the page for a data-action-for='action' tag somewhere on the page.
10
+ # If it finds it, it clicks it.
11
+ #
12
+ # `?` variant:
13
+ # It checks the page for a data-action-for='action' tag somewhere on the page.
14
+ # If it finds it, returns the Capybara element.
15
+ #
16
+ # @param action [Symbol] this is the name of the action
17
+ #
18
+ # @return [Capybara::Result]
19
+ #
20
+ # @raise [PageRecord::MultipleRecords] when there are more actions with
21
+ # this name on the page
22
+ #
23
+ def method_missing(action)
24
+ raw_action = /(.*)\?/.match(action)
25
+ begin
26
+ if raw_action
27
+ action_for?(raw_action[1])
28
+ else
29
+ action_for(action)
30
+ end
31
+ rescue Capybara::ElementNotFound
32
+ super
33
+ end
34
+ end
35
35
 
36
+ private
36
37
 
37
- private
38
+ # @private
39
+ def action_for(action)
40
+ element = action_for?(action)
41
+ element.click
42
+ element
43
+ end
38
44
 
39
- # @private
40
- def action_for(action)
41
- element = action_for?(action)
42
- element.click
43
- element
44
- end
45
-
46
- # @private
47
- def action_for?(action)
48
- @record.find("[data-action-for='#{action}']")
49
- end
50
- end
45
+ # @private
46
+ def action_for?(action)
47
+ @record.find("[data-action-for='#{action}']")
48
+ end
49
+ end
51
50
  end
52
-
@@ -1,7 +1,7 @@
1
1
  require 'page_record'
2
2
 
3
3
  RSpec.configure do |config|
4
- config.before(:each) do
4
+ config.before(:each) do
5
5
  PageRecord::Base.page session
6
6
  end
7
7
  end
@@ -0,0 +1,46 @@
1
+ require 'active_model'
2
+
3
+ module PageRecord
4
+ class Base
5
+ ##
6
+ # Searches the record for any errors and returns them
7
+ #
8
+ # @return [ActiveModel::Errors] the error object for the current record
9
+ #
10
+ # @raise [AttributeNotFound] when the attribute is not found in the record
11
+ #
12
+ def errors
13
+ found_errors = @record.all("[data-error-for]")
14
+ error_list = ActiveModel::Errors.new(self)
15
+ found_errors.each do | error |
16
+ attribute = error['data-error-for']
17
+ message = error.text
18
+ error_list.add(attribute, message)
19
+ end
20
+ error_list
21
+ end
22
+
23
+ ##
24
+ # Returns true of there are no errors on the current record
25
+ #
26
+ # @return bool
27
+ #
28
+ # @raise [AttributeNotFound] when the attribute is not found in the record
29
+ #
30
+ def valid?
31
+ errors.empty?
32
+ end
33
+
34
+ ##
35
+ # Returns true of there are errors on the current record
36
+ #
37
+ # @return bool
38
+ #
39
+ # @raise [AttributeNotFound] when the attribute is not found in the record
40
+ #
41
+ def invalid?
42
+ !valid?
43
+ end
44
+
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  module PageRecord
2
- VERSION = "0.4.0"
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/page_record.rb CHANGED
@@ -1,19 +1,17 @@
1
1
  require 'active_support/core_ext'
2
- require "page_record/version"
3
- require "page_record/base"
4
- require "page_record/finders"
5
- require "page_record/instance_actions"
6
- require "page_record/attribute_accessors"
7
- require "page_record/class_actions"
8
- require "page_record/class_methods"
9
- require "page_record/errors"
2
+ require 'page_record/version'
3
+ require 'page_record/inspector'
4
+ require 'page_record/base'
5
+ require 'page_record/finders'
6
+ require 'page_record/instance_actions'
7
+ require 'page_record/attribute_accessors'
8
+ require 'page_record/class_actions'
9
+ require 'page_record/class_methods'
10
+ require 'page_record/errors'
11
+ require 'page_record/validation'
10
12
  if defined?(ActionView::Base)
11
- require "page_record/helpers"
12
- require "page_record/form_builder"
13
+ require 'page_record/helpers'
14
+ require 'page_record/form_builder'
13
15
  end
14
- if defined?(Formtastic::Helpers::FormHelper)
15
- require "page_record/formtastic"
16
- end
17
-
18
-
16
+ require 'page_record/formtastic' if defined?(Formtastic::Helpers::FormHelper)
19
17
 
data/page_record.gemspec CHANGED
@@ -25,8 +25,11 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "sinatra"
26
26
  spec.add_development_dependency "actionpack"
27
27
  spec.add_development_dependency "activerecord"
28
+ spec.add_development_dependency "guard-rspec"
29
+ spec.add_development_dependency "ruby_gntp"
28
30
  # spec.add_development_dependency "debugger"
29
31
 
30
32
  spec.add_dependency "capybara" , '~>2.1.0'
31
33
  spec.add_dependency "activesupport"
32
- end
34
+ spec.add_dependency "activemodel"
35
+ end
data/spec/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ inherit_from: ../.rubocop.yml
2
+
3
+ StringLiterals:
4
+ Enabled: false