rails-add_ons 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/components/component/collection_table.rb +15 -4
- data/app/components/component/resource_table.rb +12 -4
- data/app/concerns/component/collection_table/awesome_nested_set_concern.rb +10 -0
- data/app/concerns/resources_controller/sorting.rb +1 -6
- data/app/views/component/_collection_table.haml +1 -4
- data/app/views/component/_resource_table.haml +1 -4
- data/app/views/component/table/body_cells/_association.haml +14 -0
- data/app/views/component/table/body_cells/_awesome_nested_set.haml +9 -0
- data/app/views/component/table/body_cells/_default.haml +4 -0
- data/app/views/component/table/body_cells/_timestamp.haml +7 -0
- data/config/locales/de.yml +2 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb +125 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_delete_action_matcher.rb +111 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_index_action_matcher.rb +65 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_show_action_matcher.rb +78 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb +141 -0
- data/lib/rails/add_ons/shoulda/matchers.rb +22 -0
- data/lib/rails/add_ons/version.rb +1 -1
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38dfc7296961120d4480e74f0e8ae4f37639d5b4
|
4
|
+
data.tar.gz: dc9461478a926c1b05b3a4d58224e7a10e39e5e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 368ee1a7318c3c181c362280a8042ba49a8e53678aff8af2506ab97e648fb9f157c7d580bb64d281672205a98565dff37b638f263ca98df6b8c8835d5654202d
|
7
|
+
data.tar.gz: 7d75f4bcda5f292c1cbec5952e7f0b480c24bafedeba2a4c72928b2d665890ee4095cd82a3c19f7280d57df26808a1cc936992be733ce7c8127d379c44f24655
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Component
|
2
2
|
class CollectionTable < Base
|
3
|
+
include AwesomeNestedSetConcern
|
4
|
+
|
3
5
|
SIZE_MAP = {
|
4
6
|
default: nil,
|
5
7
|
small: :sm
|
@@ -13,18 +15,23 @@ module Component
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def column(name, options = {}, &block)
|
18
|
+
options.reverse_merge!(render_as: :default)
|
16
19
|
options.reverse_merge!(block: block) if block_given?
|
17
20
|
@columns[name] = options
|
18
21
|
end
|
22
|
+
def timestamp(name, options = {}, &block)
|
23
|
+
options.reverse_merge!(render_as: :timestamp, format: nil)
|
24
|
+
column(name, options, &block)
|
25
|
+
end
|
19
26
|
|
20
27
|
def timestamps(options = {})
|
21
|
-
|
22
|
-
|
28
|
+
timestamp(:created_at, options)
|
29
|
+
timestamp(:updated_at, options)
|
23
30
|
end
|
24
31
|
|
25
32
|
def association(name, options = {}, &block)
|
26
|
-
options.reverse_merge!(
|
27
|
-
|
33
|
+
options.reverse_merge!(render_as: :association)
|
34
|
+
column(name, options, &block)
|
28
35
|
end
|
29
36
|
|
30
37
|
private
|
@@ -76,5 +83,9 @@ module Component
|
|
76
83
|
classes << "table-#{size}" if size.present?
|
77
84
|
classes
|
78
85
|
end
|
86
|
+
|
87
|
+
def t(key, options = {})
|
88
|
+
I18n.t("#{self.class.name.underscore.gsub('/', '.')}#{key}", options)
|
89
|
+
end
|
79
90
|
end
|
80
91
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Component
|
2
2
|
class ResourceTable < Base
|
3
|
+
attr_reader :resource
|
4
|
+
|
3
5
|
def initialize(*args)
|
4
6
|
super
|
5
7
|
@rows = {}
|
@@ -8,18 +10,24 @@ module Component
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def row(name, options = {}, &block)
|
13
|
+
options.reverse_merge!(render_as: :default)
|
11
14
|
options.reverse_merge!(block: block) if block_given?
|
12
15
|
@rows[name] = options
|
13
16
|
end
|
14
17
|
|
18
|
+
def timestamp(name, options = {}, &block)
|
19
|
+
options.reverse_merge!(render_as: :timestamp, format: nil)
|
20
|
+
row(name, options, &block)
|
21
|
+
end
|
22
|
+
|
15
23
|
def timestamps(options = {})
|
16
|
-
|
17
|
-
|
24
|
+
timestamp(:created_at, options)
|
25
|
+
timestamp(:updated_at, options)
|
18
26
|
end
|
19
27
|
|
20
28
|
def association(name, options = {}, &block)
|
21
|
-
options.reverse_merge!(
|
22
|
-
|
29
|
+
options.reverse_merge!(render_as: :association)
|
30
|
+
row(name, options, &block)
|
23
31
|
end
|
24
32
|
|
25
33
|
private
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Component
|
2
|
+
module CollectionTable::AwesomeNestedSetConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def awesome_nested_set_actions(name, options = {}, &block)
|
6
|
+
options.reverse_merge!(render_as: :awesome_nested_set, scope: nil, title: t('.column_titles.awesome_nested_set'))
|
7
|
+
column(name, options, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -12,12 +12,7 @@ module ResourcesController::Sorting
|
|
12
12
|
end
|
13
13
|
|
14
14
|
sort_direction = (params[:sort_direction] || :asc)
|
15
|
-
|
16
|
-
if Rails.version < '4.0.0'
|
17
|
-
base_scope.order("#{params[:sort_by]} #{sort_direction}")
|
18
|
-
else
|
19
|
-
base_scope.order(params[:sort_by] => sort_direction)
|
20
|
-
end
|
15
|
+
base_scope.reorder("#{params[:sort_by]} #{sort_direction}")
|
21
16
|
else
|
22
17
|
base_scope
|
23
18
|
end
|
@@ -26,7 +26,4 @@
|
|
26
26
|
%td{ td_options }= options[:block].call(resource)
|
27
27
|
- else
|
28
28
|
%td{ td_options }
|
29
|
-
|
30
|
-
= resource.send(name).send(options[:label_method])
|
31
|
-
- else
|
32
|
-
= resource.send(name)
|
29
|
+
= render partial: "component/table/body_cells/#{options[:render_as]}", locals: { resource: resource, name: name, options: options }
|
@@ -12,7 +12,4 @@
|
|
12
12
|
= options[:block].call(resource)
|
13
13
|
- else
|
14
14
|
%td
|
15
|
-
|
16
|
-
= resource.send(name).send(options[:label_method])
|
17
|
-
- else
|
18
|
-
= resource.send(name)
|
15
|
+
= render partial: "component/table/body_cells/#{options[:render_as]}", locals: { resource: resource, name: name, options: options }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
- label = if options[:label_method].present?
|
2
|
+
- resource.send(name).send(options[:label_method])
|
3
|
+
- else
|
4
|
+
- resource.send(name)
|
5
|
+
- link_to = options[:link_to]
|
6
|
+
- case link_to
|
7
|
+
- when Proc
|
8
|
+
= link_to(label, link_to.call(resource))
|
9
|
+
- when String
|
10
|
+
= link_to(label, link_to)
|
11
|
+
- when Symbol
|
12
|
+
= link_to(label, send(link_to))
|
13
|
+
- when nil
|
14
|
+
= label
|
@@ -0,0 +1,9 @@
|
|
1
|
+
:ruby
|
2
|
+
data_attributes = {
|
3
|
+
'awesome-nested-set-item': true,
|
4
|
+
'awesome-nested-set-item-uid': resource.to_param,
|
5
|
+
'awesome-nested-set-item-on-drop-target': url_for([:reposition, resource])
|
6
|
+
}
|
7
|
+
data_attributes['awesome-nested-set-item-scope'] = scope.call(model) if options[:scope].present?
|
8
|
+
%span.btn.btn-xs.btn-default.awesome-nested-set-item{ data: data_attributes }
|
9
|
+
%span.glyphicon.glyphicon-sort
|
data/config/locales/de.yml
CHANGED
@@ -0,0 +1,125 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# RSpec.describe '/posts', type: :feature do
|
8
|
+
# it {
|
9
|
+
# expect(subject).to implement_create_action(self)
|
10
|
+
# .for(Post)
|
11
|
+
# .within_form('#new_post') {
|
12
|
+
# fill_in 'post[title]', with: 'My first post'
|
13
|
+
# }
|
14
|
+
# .increasing{ |resource_class| resource_class.count }.by(1)
|
15
|
+
# }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
def implement_create_action(spec)
|
19
|
+
ImplementCreateActionMatcher.new(spec)
|
20
|
+
end
|
21
|
+
|
22
|
+
class ImplementCreateActionMatcher
|
23
|
+
include RSpec::Matchers
|
24
|
+
|
25
|
+
def initialize(spec)
|
26
|
+
@spec = spec
|
27
|
+
end
|
28
|
+
|
29
|
+
def id(id)
|
30
|
+
@id = id
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def increasing(&block)
|
35
|
+
@block = block
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def by(expected_increase)
|
40
|
+
@expected_increase = expected_increase
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Resource class that will be created
|
45
|
+
def for(resource_class)
|
46
|
+
@resource_class = resource_class
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Specifies the form css id to fill to create the resource.
|
51
|
+
def within_form(id, &block)
|
52
|
+
@form_id = id
|
53
|
+
@form_block = block
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def matches?(base_path)
|
58
|
+
@base_path = base_path
|
59
|
+
@new_path = "#{@base_path}/new"
|
60
|
+
|
61
|
+
@spec.visit(@new_path)
|
62
|
+
|
63
|
+
@before_count = @block.call(@resource_class)
|
64
|
+
@spec.within(@form_id) do
|
65
|
+
@form_block.call
|
66
|
+
@spec.find('input[name="commit"]').click
|
67
|
+
end
|
68
|
+
@after_count = @block.call(@resource_class)
|
69
|
+
|
70
|
+
has_correct_status_code && has_correct_current_path && has_increased_resource_count
|
71
|
+
end
|
72
|
+
|
73
|
+
def created_resource
|
74
|
+
@created_resource ||= @resource_class.first
|
75
|
+
end
|
76
|
+
|
77
|
+
def expected_path
|
78
|
+
@expected_path ||= "#{@base_path}/#{created_resource.to_param}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def has_correct_status_code
|
82
|
+
if @spec.status_code == 200
|
83
|
+
true
|
84
|
+
else
|
85
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def has_increased_resource_count
|
91
|
+
if (@before_count + @after_count) == @expected_increase
|
92
|
+
true
|
93
|
+
else
|
94
|
+
@error = "Did not increase by expected [#{@expected_increase}] but by [#{@before_count + @after_count}]"
|
95
|
+
false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def has_correct_current_path
|
100
|
+
if @spec.current_path == expected_path
|
101
|
+
true
|
102
|
+
else
|
103
|
+
@error = "Wrong current path [#{@spec.current_path}] instead of [#{expected_path}]"
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def failure_message
|
109
|
+
"Should expose create action on #{@new_path}. Error: #{@error}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def failure_message_when_negated
|
113
|
+
"Should not expose create action on #{@new_path}. Error: #{@error}"
|
114
|
+
end
|
115
|
+
|
116
|
+
alias negative_failure_message failure_message_when_negated
|
117
|
+
|
118
|
+
def description
|
119
|
+
"expose create action on #{@new_path}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# RSpec.describe '/posts', type: :feature do
|
8
|
+
# let(:resource_class) { Post }
|
9
|
+
# let(:resource) { create(:post) }
|
10
|
+
#
|
11
|
+
# it {
|
12
|
+
# expect(subject).to implement_delete_action(self)
|
13
|
+
# .for(resource)
|
14
|
+
# .reducing{ resource_class.count }.by(1)
|
15
|
+
# }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
def implement_delete_action(spec)
|
19
|
+
ImplementDeleteActionMatcher.new(spec)
|
20
|
+
end
|
21
|
+
|
22
|
+
class ImplementDeleteActionMatcher
|
23
|
+
include RSpec::Matchers
|
24
|
+
|
25
|
+
def initialize(spec)
|
26
|
+
@spec = spec
|
27
|
+
end
|
28
|
+
|
29
|
+
# Resource that will be deleted
|
30
|
+
def for(resource)
|
31
|
+
@resource = resource
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def id
|
36
|
+
@resource.to_param
|
37
|
+
end
|
38
|
+
|
39
|
+
def reducing(&block)
|
40
|
+
@block = block
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def by(expected_reduction)
|
45
|
+
@expected_reduction = expected_reduction
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def matches?(base_path)
|
50
|
+
@base_path = base_path
|
51
|
+
@expected_path = @base_path
|
52
|
+
@show_path = "#{@base_path}/#{id}"
|
53
|
+
|
54
|
+
@spec.visit(@show_path)
|
55
|
+
|
56
|
+
@before_delete_count = @block.call
|
57
|
+
@spec.click_link(delete_link_text)
|
58
|
+
@after_delete_count = @block.call
|
59
|
+
|
60
|
+
has_correct_status_code && has_correct_current_path && has_reduced_resource_count
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete_link_text
|
64
|
+
@delete_link_text ||= I18n.t('resources_controller.base.show_actions.delete')
|
65
|
+
end
|
66
|
+
|
67
|
+
def has_correct_status_code
|
68
|
+
if @spec.status_code == 200
|
69
|
+
true
|
70
|
+
else
|
71
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def has_reduced_resource_count
|
77
|
+
if (@before_delete_count - @after_delete_count) == @expected_reduction
|
78
|
+
true
|
79
|
+
else
|
80
|
+
@error = "Did not reduce by expected [#{@expected_reduction}] but by [#{@before_delete_count - @after_delete_count}]"
|
81
|
+
false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_correct_current_path
|
86
|
+
if @spec.current_path == @expected_path
|
87
|
+
true
|
88
|
+
else
|
89
|
+
@error = "Wrong current path [#{@spec.current_path}] instead of [#{@expected_path}]"
|
90
|
+
false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def failure_message
|
95
|
+
"Should expose delete action on #{@base_path} [#{delete_link_text}], clicking on #{delete_link_text}. Error: #{@error}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def failure_message_when_negated
|
99
|
+
"Should not expose delete action on #{@base_path} [#{delete_link_text}], clicking on #{delete_link_text}. Error: #{@error}"
|
100
|
+
end
|
101
|
+
|
102
|
+
alias negative_failure_message failure_message_when_negated
|
103
|
+
|
104
|
+
def description
|
105
|
+
"expose delete action on #{@base_path} [#{delete_link_text}]"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# RSpec.describe '/posts', type: :feature do
|
8
|
+
# before(:each) { create_list(:post, 3) }
|
9
|
+
#
|
10
|
+
# it { expect(subject).to implement_index_action(self) }
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
def implement_index_action(spec)
|
14
|
+
ImplementIndexActionMatcher.new(spec)
|
15
|
+
end
|
16
|
+
|
17
|
+
class ImplementIndexActionMatcher
|
18
|
+
include RSpec::Matchers
|
19
|
+
|
20
|
+
def initialize(spec)
|
21
|
+
@spec = spec
|
22
|
+
end
|
23
|
+
|
24
|
+
def matches?(base_path)
|
25
|
+
@base_path = base_path
|
26
|
+
@spec.visit(@base_path)
|
27
|
+
has_correct_status_code && has_correct_current_path
|
28
|
+
end
|
29
|
+
|
30
|
+
def has_correct_status_code
|
31
|
+
if @spec.status_code == 200
|
32
|
+
true
|
33
|
+
else
|
34
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_correct_current_path
|
40
|
+
if @spec.current_path == @base_path
|
41
|
+
true
|
42
|
+
else
|
43
|
+
@error = "Wrong current path [#{@spec.current_path}] instead of [#{@base_path}]"
|
44
|
+
false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def failure_message
|
49
|
+
"Should expose index action on #{@base_path}. Error: #{@error}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def failure_message_when_negated
|
53
|
+
"Should not expose index action on #{@base_path}. Error: #{@error}"
|
54
|
+
end
|
55
|
+
|
56
|
+
alias negative_failure_message failure_message_when_negated
|
57
|
+
|
58
|
+
def description
|
59
|
+
"expose index action on #{@base_path}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# RSpec.describe '/posts', type: :feature do
|
8
|
+
# let(:resource) { create(:post) }
|
9
|
+
#
|
10
|
+
# it { expect(subject).to implement_show_action(self).for(resource) }
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
def implement_show_action(spec)
|
14
|
+
ImplementShowActionMatcher.new(spec)
|
15
|
+
end
|
16
|
+
|
17
|
+
class ImplementShowActionMatcher
|
18
|
+
include RSpec::Matchers
|
19
|
+
|
20
|
+
def initialize(spec)
|
21
|
+
@spec = spec
|
22
|
+
end
|
23
|
+
|
24
|
+
# Resource that will be updated
|
25
|
+
def for(resource)
|
26
|
+
@resource = resource
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def id
|
31
|
+
@resource.to_param
|
32
|
+
end
|
33
|
+
|
34
|
+
def matches?(base_path)
|
35
|
+
@base_path = base_path
|
36
|
+
@expected_path = "#{@base_path}/#{id}"
|
37
|
+
|
38
|
+
@spec.visit(@expected_path)
|
39
|
+
|
40
|
+
has_correct_status_code && has_correct_current_path
|
41
|
+
end
|
42
|
+
|
43
|
+
def has_correct_status_code
|
44
|
+
if @spec.status_code == 200
|
45
|
+
true
|
46
|
+
else
|
47
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def has_correct_current_path
|
53
|
+
if @spec.current_path == @expected_path
|
54
|
+
true
|
55
|
+
else
|
56
|
+
@error = "Wrong current path [#{@spec.current_path}] instead of [#{@expected_path}]"
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def failure_message
|
62
|
+
"Should expose show action on #{@base_path}. Error: #{@error}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def failure_message_when_negated
|
66
|
+
"Should not expose show action on #{@base_path}. Error: #{@error}"
|
67
|
+
end
|
68
|
+
|
69
|
+
alias negative_failure_message failure_message_when_negated
|
70
|
+
|
71
|
+
def description
|
72
|
+
"expose show action on #{@base_path}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# RSpec.describe '/posts', type: :feature do
|
8
|
+
# let(:post) { create(:post) }
|
9
|
+
# it {
|
10
|
+
# expect(subject).to implement_update_action(self)
|
11
|
+
# .for(post)
|
12
|
+
# .within_form('.edit_post') {
|
13
|
+
# fill_in 'post[title]', with: 'New title'
|
14
|
+
# fill_in 'post[body]', with: 'New body'
|
15
|
+
# }
|
16
|
+
# .updating{ |resource| resource.attributes }
|
17
|
+
# .from(post.attributes)
|
18
|
+
# .to({ 'title' => 'New title', 'body' => 'New body' })
|
19
|
+
# }
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
def implement_update_action(spec)
|
23
|
+
ImplementUpdateActionMatcher.new(spec)
|
24
|
+
end
|
25
|
+
|
26
|
+
class ImplementUpdateActionMatcher
|
27
|
+
include RSpec::Matchers
|
28
|
+
|
29
|
+
def initialize(spec)
|
30
|
+
@spec = spec
|
31
|
+
end
|
32
|
+
|
33
|
+
# Resource that will be updated
|
34
|
+
def for(resource)
|
35
|
+
@resource = resource
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def from(attributes)
|
40
|
+
@expected_before_attributes = attributes
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def to(attributes)
|
45
|
+
@expected_after_attributes = attributes
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# Specifies the form css id to fill to create the resource.
|
50
|
+
def within_form(id, &block)
|
51
|
+
@form_id = id
|
52
|
+
@form_block = block
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def updating(&block)
|
57
|
+
@block = block
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def id
|
62
|
+
@resource.to_param
|
63
|
+
end
|
64
|
+
|
65
|
+
def matches?(base_path)
|
66
|
+
@base_path = base_path
|
67
|
+
@show_path = "#{@base_path}/#{id}"
|
68
|
+
@edit_path = "#{@base_path}/#{id}/edit"
|
69
|
+
|
70
|
+
@expected_path = @show_path
|
71
|
+
|
72
|
+
@spec.visit(@edit_path)
|
73
|
+
|
74
|
+
return unless has_correct_attributes_before if @expected_before_attributes.present?
|
75
|
+
|
76
|
+
@spec.within(@form_id) do
|
77
|
+
@form_block.call
|
78
|
+
@spec.find('input[name="commit"]').click
|
79
|
+
end
|
80
|
+
|
81
|
+
@resource.reload
|
82
|
+
|
83
|
+
has_correct_status_code && has_correct_current_path && has_correct_attributes_after
|
84
|
+
end
|
85
|
+
|
86
|
+
def has_correct_status_code
|
87
|
+
if @spec.status_code == 200
|
88
|
+
true
|
89
|
+
else
|
90
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def has_correct_current_path
|
96
|
+
if @spec.current_path == @expected_path
|
97
|
+
true
|
98
|
+
else
|
99
|
+
@error = "Wrong current path [#{@spec.current_path}] instead of [#{@expected_path}]"
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def has_correct_attributes_before
|
105
|
+
sliced_resource_attributes = @resource.attributes.with_indifferent_access.slice(*@expected_before_attributes.keys)
|
106
|
+
if @expected_before_attributes == sliced_resource_attributes
|
107
|
+
true
|
108
|
+
else
|
109
|
+
@error = "Attributes before update [#{sliced_resource_attributes}] did not match expected attributes [#{@expected_before_attributes}]"
|
110
|
+
false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def has_correct_attributes_after
|
115
|
+
sliced_resource_attributes = @resource.attributes.with_indifferent_access.slice(*@expected_after_attributes.keys)
|
116
|
+
if @expected_after_attributes == sliced_resource_attributes
|
117
|
+
true
|
118
|
+
else
|
119
|
+
@error = "Attributes after update [#{sliced_resource_attributes}] did not match expected attributes [#{@expected_after_attributes}]"
|
120
|
+
false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def failure_message
|
125
|
+
"Should expose update action on #{@edit_path}. Error: #{@error}"
|
126
|
+
end
|
127
|
+
|
128
|
+
def failure_message_when_negated
|
129
|
+
"Should not expose update action on #{@edit_path}. Error: #{@error}"
|
130
|
+
end
|
131
|
+
|
132
|
+
alias negative_failure_message failure_message_when_negated
|
133
|
+
|
134
|
+
def description
|
135
|
+
"expose update action on #{@edit_path}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails/add_ons/shoulda/matchers/implement_create_action_matcher'
|
2
|
+
require 'rails/add_ons/shoulda/matchers/implement_show_action_matcher'
|
3
|
+
require 'rails/add_ons/shoulda/matchers/implement_update_action_matcher'
|
4
|
+
require 'rails/add_ons/shoulda/matchers/implement_delete_action_matcher'
|
5
|
+
require 'rails/add_ons/shoulda/matchers/implement_index_action_matcher'
|
6
|
+
|
7
|
+
module Rails
|
8
|
+
module AddOns
|
9
|
+
module Shoulda
|
10
|
+
# Adding the matchers to rspec:
|
11
|
+
#
|
12
|
+
# # spec/rails_helper or supoprt/rails-add_ons.rb
|
13
|
+
# require 'rails/add_ons/shoulda/matchers'
|
14
|
+
#
|
15
|
+
# RSpec.configure do |config|
|
16
|
+
# config.include Rails::AddOns::Shoulda::Matchers, type: :feature
|
17
|
+
# end
|
18
|
+
module Matchers
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-add_ons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Vasquez Angel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -190,6 +190,7 @@ files:
|
|
190
190
|
- app/components/component/collection_table.rb
|
191
191
|
- app/components/component/resource_table.rb
|
192
192
|
- app/concerns/api_controller_concerns/exception_handling.rb
|
193
|
+
- app/concerns/component/collection_table/awesome_nested_set_concern.rb
|
193
194
|
- app/concerns/controller/query_conditions.rb
|
194
195
|
- app/concerns/resources_controller/kaminari.rb
|
195
196
|
- app/concerns/resources_controller/location_history.rb
|
@@ -220,6 +221,10 @@ files:
|
|
220
221
|
- app/services/rails/add_ons/service/result/base.rb
|
221
222
|
- app/views/component/_collection_table.haml
|
222
223
|
- app/views/component/_resource_table.haml
|
224
|
+
- app/views/component/table/body_cells/_association.haml
|
225
|
+
- app/views/component/table/body_cells/_awesome_nested_set.haml
|
226
|
+
- app/views/component/table/body_cells/_default.haml
|
227
|
+
- app/views/component/table/body_cells/_timestamp.haml
|
223
228
|
- app/views/frontend/_after_body.haml
|
224
229
|
- app/views/frontend/_after_head.haml
|
225
230
|
- app/views/frontend/_before_body.haml
|
@@ -260,6 +265,12 @@ files:
|
|
260
265
|
- lib/rails-add_ons.rb
|
261
266
|
- lib/rails/add_ons.rb
|
262
267
|
- lib/rails/add_ons/engine.rb
|
268
|
+
- lib/rails/add_ons/shoulda/matchers.rb
|
269
|
+
- lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb
|
270
|
+
- lib/rails/add_ons/shoulda/matchers/implement_delete_action_matcher.rb
|
271
|
+
- lib/rails/add_ons/shoulda/matchers/implement_index_action_matcher.rb
|
272
|
+
- lib/rails/add_ons/shoulda/matchers/implement_show_action_matcher.rb
|
273
|
+
- lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb
|
263
274
|
- lib/rails/add_ons/version.rb
|
264
275
|
- lib/tasks/rails/add_ons_tasks.rake
|
265
276
|
homepage:
|