rails-add_ons 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|