standardapi 6.0.0.26 → 6.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/README.md +15 -6
- data/lib/standard_api.rb +5 -0
- data/lib/standard_api/access_control_list.rb +114 -0
- data/lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb +21 -0
- data/lib/standard_api/controller.rb +75 -78
- data/lib/standard_api/errors.rb +9 -0
- data/lib/standard_api/helpers.rb +66 -13
- data/lib/standard_api/includes.rb +9 -0
- data/lib/standard_api/middleware/query_encoding.rb +3 -3
- data/lib/standard_api/railtie.rb +13 -2
- data/lib/standard_api/route_helpers.rb +5 -5
- data/lib/standard_api/test_case.rb +24 -14
- data/lib/standard_api/test_case/calculate_tests.rb +10 -4
- data/lib/standard_api/test_case/create_tests.rb +13 -15
- data/lib/standard_api/test_case/index_tests.rb +14 -4
- data/lib/standard_api/test_case/schema_tests.rb +25 -3
- data/lib/standard_api/test_case/show_tests.rb +1 -0
- data/lib/standard_api/test_case/update_tests.rb +8 -9
- data/lib/standard_api/version.rb +1 -1
- data/lib/standard_api/views/application/_record.json.jbuilder +33 -30
- data/lib/standard_api/views/application/_record.streamer +36 -34
- data/lib/standard_api/views/application/_schema.json.jbuilder +68 -0
- data/lib/standard_api/views/application/_schema.streamer +78 -0
- data/lib/standard_api/views/application/new.streamer +1 -1
- data/lib/standard_api/views/application/schema.json.jbuilder +1 -12
- data/lib/standard_api/views/application/schema.streamer +1 -16
- data/test/standard_api/caching_test.rb +43 -0
- data/test/standard_api/helpers_test.rb +172 -0
- data/test/standard_api/performance.rb +39 -0
- data/test/standard_api/route_helpers_test.rb +33 -0
- data/test/standard_api/standard_api_test.rb +699 -0
- data/test/standard_api/test_app.rb +1 -0
- data/test/standard_api/test_app/app/controllers/acl/account_acl.rb +15 -0
- data/test/standard_api/test_app/app/controllers/acl/property_acl.rb +27 -0
- data/test/standard_api/test_app/app/controllers/acl/reference_acl.rb +7 -0
- data/test/standard_api/test_app/controllers.rb +13 -45
- data/test/standard_api/test_app/models.rb +38 -4
- data/test/standard_api/test_app/test/factories.rb +4 -3
- data/test/standard_api/test_app/views/photos/_photo.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/_photo.streamer +18 -0
- data/test/standard_api/test_app/views/photos/_schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/_schema.streamer +3 -0
- data/test/standard_api/test_app/views/photos/schema.json.jbuilder +1 -1
- data/test/standard_api/test_app/views/photos/schema.streamer +1 -0
- data/test/standard_api/test_helper.rb +238 -0
- metadata +33 -17
- data/test/standard_api/test_app/log/test.log +0 -129516
@@ -37,6 +37,7 @@ require 'standard_api/test_app/controllers'
|
|
37
37
|
# Test Application Routes
|
38
38
|
Rails.application.routes.draw do
|
39
39
|
get :tables, to: 'application#tables', as: :tables
|
40
|
+
get :schema, to: 'application#schema', as: :schema
|
40
41
|
|
41
42
|
[:properties, :photos, :documents, :references, :sessions, :unlimited, :default_limit].each do |r|
|
42
43
|
standard_resources r
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PropertyACL
|
2
|
+
|
3
|
+
def attributes
|
4
|
+
[ :name,
|
5
|
+
:aliases,
|
6
|
+
:description,
|
7
|
+
:constructed,
|
8
|
+
:size,
|
9
|
+
:active
|
10
|
+
# :photos_attributes,
|
11
|
+
# { photos_attributes: [ :id, :account_id, :property_id, :format] }
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
def orders
|
16
|
+
["id", "name", "aliases", "description", "constructed", "size", "created_at", "active"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def includes
|
20
|
+
[ :photos, :landlord, :english_name, :document ]
|
21
|
+
end
|
22
|
+
|
23
|
+
def nested
|
24
|
+
[ :photos ]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -1,77 +1,45 @@
|
|
1
1
|
class ApplicationController < ActionController::Base
|
2
2
|
include StandardAPI::Controller
|
3
|
+
include StandardAPI::AccessControlList
|
3
4
|
prepend_view_path File.join(File.dirname(__FILE__), 'views')
|
4
5
|
|
5
|
-
private
|
6
|
-
|
7
|
-
def account_params
|
8
|
-
[ "property_id", "name" ]
|
9
|
-
end
|
10
|
-
|
11
|
-
def account_orders
|
12
|
-
[ "id" ]
|
13
|
-
end
|
14
|
-
|
15
|
-
def account_includes
|
16
|
-
[ "photos" ]
|
17
|
-
end
|
18
|
-
|
19
|
-
def property_params
|
20
|
-
[ :name,
|
21
|
-
:aliases,
|
22
|
-
:description,
|
23
|
-
:constructed,
|
24
|
-
:size,
|
25
|
-
:active,
|
26
|
-
:photos_attributes,
|
27
|
-
{ photos_attributes: [ :id, :account_id, :property_id, :format] }
|
28
|
-
]
|
29
|
-
end
|
30
|
-
|
31
|
-
def property_orders
|
32
|
-
["id", "name", "aliases", "description", "constructed", "size", "created_at", "active"]
|
33
|
-
end
|
34
|
-
|
35
|
-
def property_includes
|
36
|
-
[:photos, :landlord, :english_name]
|
37
|
-
end
|
38
|
-
|
39
|
-
def reference_includes
|
40
|
-
{ subject: [ :landlord, :photos ] }
|
41
|
-
end
|
42
|
-
|
43
6
|
end
|
44
7
|
|
45
8
|
class PropertiesController < ApplicationController
|
46
9
|
end
|
47
10
|
|
48
11
|
class AccountsController < ApplicationController
|
12
|
+
|
13
|
+
def show
|
14
|
+
@account = Account.last
|
15
|
+
end
|
16
|
+
|
49
17
|
end
|
50
18
|
|
51
19
|
class DocumentsController < ApplicationController
|
52
20
|
|
53
|
-
def
|
21
|
+
def document_attributes
|
54
22
|
[ :file, :type ]
|
55
23
|
end
|
56
|
-
|
24
|
+
|
57
25
|
def document_orders
|
58
|
-
[:id]
|
26
|
+
[ :id ]
|
59
27
|
end
|
60
28
|
|
61
29
|
end
|
62
30
|
|
63
31
|
class PhotosController < ApplicationController
|
64
32
|
|
65
|
-
def
|
33
|
+
def photo_attributes
|
66
34
|
[ :id, :account_id, :property_id, :format ]
|
67
35
|
end
|
68
36
|
|
69
37
|
def photo_orders
|
70
|
-
[:id]
|
38
|
+
[ :id ]
|
71
39
|
end
|
72
40
|
|
73
41
|
def photo_includes
|
74
|
-
[:account]
|
42
|
+
[ :account ]
|
75
43
|
end
|
76
44
|
|
77
45
|
end
|
@@ -104,4 +72,4 @@ class DefaultLimitController < ApplicationController
|
|
104
72
|
100
|
105
73
|
end
|
106
74
|
|
107
|
-
end
|
75
|
+
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# = Models
|
2
2
|
|
3
3
|
class Account < ActiveRecord::Base
|
4
|
-
has_many :photos
|
4
|
+
has_many :photos, -> { order(:created_at) }
|
5
5
|
belongs_to :property
|
6
|
+
belongs_to :subject, polymorphic: true
|
6
7
|
end
|
7
8
|
|
8
9
|
class Photo < ActiveRecord::Base
|
@@ -21,6 +22,9 @@ class Property < ActiveRecord::Base
|
|
21
22
|
has_and_belongs_to_many :photos
|
22
23
|
has_many :accounts
|
23
24
|
has_one :landlord, class_name: 'Account'
|
25
|
+
has_one :document_attachments, class_name: "Attachment", as: :record, inverse_of: :record
|
26
|
+
has_one :document, through: "document_attachments"
|
27
|
+
|
24
28
|
|
25
29
|
validates :name, presence: true
|
26
30
|
accepts_nested_attributes_for :photos
|
@@ -34,22 +38,46 @@ class Reference < ActiveRecord::Base
|
|
34
38
|
belongs_to :subject, polymorphic: true
|
35
39
|
end
|
36
40
|
|
41
|
+
class Document < ActiveRecord::Base
|
42
|
+
attr_accessor :file
|
43
|
+
end
|
44
|
+
|
45
|
+
class Attachment < ActiveRecord::Base
|
46
|
+
belongs_to :record, polymorphic: true
|
47
|
+
belongs_to :document
|
48
|
+
end
|
49
|
+
|
37
50
|
# = Migration
|
38
51
|
|
39
|
-
class CreateModelTables < ActiveRecord::Migration[
|
52
|
+
class CreateModelTables < ActiveRecord::Migration[6.0]
|
40
53
|
|
41
54
|
def self.up
|
42
55
|
|
56
|
+
comment = "test comment"
|
57
|
+
exec_query(<<-SQL, "SQL")
|
58
|
+
COMMENT ON DATABASE #{quote_column_name(current_database)} IS #{quote(comment)};
|
59
|
+
SQL
|
60
|
+
|
43
61
|
create_table "accounts", force: :cascade do |t|
|
44
62
|
t.string 'name', limit: 255
|
45
63
|
t.integer 'property_id'
|
64
|
+
t.integer "subject_id"
|
65
|
+
t.string "subject_type"
|
66
|
+
t.datetime "property_cached_at"
|
67
|
+
t.datetime "subject_cached_at"
|
46
68
|
t.integer 'photos_count', null: false, default: 0
|
69
|
+
t.datetime "created_at", null: false
|
70
|
+
end
|
71
|
+
|
72
|
+
create_table "landlords", force: :cascade do |t|
|
73
|
+
t.string "name"
|
47
74
|
end
|
48
75
|
|
49
76
|
create_table "photos", force: :cascade do |t|
|
50
77
|
t.integer "account_id"
|
51
78
|
t.integer "property_id"
|
52
79
|
t.string "format", limit: 255
|
80
|
+
t.datetime "created_at", null: false
|
53
81
|
end
|
54
82
|
|
55
83
|
create_table "properties", force: :cascade do |t|
|
@@ -68,12 +96,12 @@ class CreateModelTables < ActiveRecord::Migration[5.2]
|
|
68
96
|
t.string "key"
|
69
97
|
t.string "value"
|
70
98
|
end
|
71
|
-
|
99
|
+
|
72
100
|
create_table "photos_properties", force: :cascade do |t|
|
73
101
|
t.integer "photo_id"
|
74
102
|
t.integer "property_id"
|
75
103
|
end
|
76
|
-
|
104
|
+
|
77
105
|
create_table "landlords_properties", force: :cascade do |t|
|
78
106
|
t.integer "landlord_id"
|
79
107
|
t.integer "property_id"
|
@@ -82,6 +110,12 @@ class CreateModelTables < ActiveRecord::Migration[5.2]
|
|
82
110
|
create_table "documents", force: :cascade do |t|
|
83
111
|
t.string 'type'
|
84
112
|
end
|
113
|
+
|
114
|
+
create_table "attachments", force: :cascade do |t|
|
115
|
+
t.string 'record_type'
|
116
|
+
t.integer 'record_id'
|
117
|
+
t.integer 'document_id'
|
118
|
+
end
|
85
119
|
end
|
86
120
|
|
87
121
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
FactoryBot.define do
|
2
|
+
|
2
3
|
factory :account do
|
3
4
|
name { Faker::Name.name }
|
4
5
|
|
@@ -7,7 +8,7 @@ FactoryBot.define do
|
|
7
8
|
name { nil }
|
8
9
|
end
|
9
10
|
end
|
10
|
-
|
11
|
+
|
11
12
|
factory :landlord do
|
12
13
|
name { Faker::Name.name }
|
13
14
|
end
|
@@ -17,12 +18,12 @@ FactoryBot.define do
|
|
17
18
|
end
|
18
19
|
|
19
20
|
factory :document do
|
20
|
-
file {
|
21
|
+
file { Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/photo.png'), 'image/png') }
|
21
22
|
end
|
22
23
|
|
23
24
|
factory :pdf do
|
24
25
|
type { 'Pdf' }
|
25
|
-
file {
|
26
|
+
file { Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/photo.png'), 'image/png') }
|
26
27
|
end
|
27
28
|
|
28
29
|
factory :reference do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
json.object! do
|
2
|
+
json.set! :id, photo.id
|
3
|
+
json.set! :account_id, photo.account_id
|
4
|
+
json.set! :property_id, photo.property_id
|
5
|
+
json.set! :format, photo.format
|
6
|
+
json.set! :created_at, photo.created_at
|
7
|
+
json.set! :template, 'photos/_photo'
|
8
|
+
|
9
|
+
if includes[:account]
|
10
|
+
json.set! :account do
|
11
|
+
if photo.account
|
12
|
+
json.partial! 'application/record', record: photo.account, includes: includes[:account]
|
13
|
+
else
|
14
|
+
json.value! nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
json.set! 'template', 'photos/schema'
|
@@ -1 +1 @@
|
|
1
|
-
json.
|
1
|
+
json.partial! 'schema'
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! 'schema'
|
@@ -0,0 +1,238 @@
|
|
1
|
+
require File.expand_path('../test_app', __FILE__)
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require 'minitest/unit'
|
5
|
+
require 'factory_bot'
|
6
|
+
require 'faker'
|
7
|
+
require 'standard_api/test_case'
|
8
|
+
require 'byebug'
|
9
|
+
require 'mocha/minitest'
|
10
|
+
|
11
|
+
# Setup the test db
|
12
|
+
ActiveSupport.test_order = :random
|
13
|
+
|
14
|
+
include ActionDispatch::TestProcess
|
15
|
+
|
16
|
+
class ActiveSupport::TestCase
|
17
|
+
include ActiveRecord::TestFixtures
|
18
|
+
include FactoryBot::Syntax::Methods
|
19
|
+
|
20
|
+
def setup
|
21
|
+
@routes ||= TestApplication.routes
|
22
|
+
@subscribers, @layouts, @partials = [], {}, {}
|
23
|
+
|
24
|
+
Rails.cache.clear
|
25
|
+
|
26
|
+
@subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
|
27
|
+
path = payload[:identifier]
|
28
|
+
virtual_path = payload[:virtual_path]
|
29
|
+
format, handler = *path.split("/").last.split('.').last(2)
|
30
|
+
|
31
|
+
partial = virtual_path =~ /^.*\/_[^\/]*$/
|
32
|
+
|
33
|
+
if partial
|
34
|
+
if @partials[virtual_path]
|
35
|
+
@partials[virtual_path][:count] += 1
|
36
|
+
else
|
37
|
+
@partials[virtual_path] = {
|
38
|
+
count: 1,
|
39
|
+
path: virtual_path,
|
40
|
+
format: format,
|
41
|
+
handler: handler
|
42
|
+
}
|
43
|
+
end
|
44
|
+
else
|
45
|
+
if @layouts[virtual_path]
|
46
|
+
@layouts[virtual_path][:count] += 1
|
47
|
+
else
|
48
|
+
@layouts[virtual_path] = {
|
49
|
+
count: 1,
|
50
|
+
path: virtual_path,
|
51
|
+
format: format,
|
52
|
+
handler: handler
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def teardown
|
60
|
+
@subscribers.each do |subscriber|
|
61
|
+
ActiveSupport::Notifications.unsubscribe(subscriber)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# = Helper Methods
|
66
|
+
|
67
|
+
def controller_path
|
68
|
+
if defined?(@controller)
|
69
|
+
@controller.controller_path
|
70
|
+
else
|
71
|
+
controller_class.new.controller_path
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def path_with_action(action, options={})
|
76
|
+
{ :controller => controller_path, :action => action }.merge(options)
|
77
|
+
end
|
78
|
+
|
79
|
+
def assert_sql(sql, &block)
|
80
|
+
queries = []
|
81
|
+
callback = -> (*, payload) do
|
82
|
+
queries << payload[:sql]
|
83
|
+
end
|
84
|
+
|
85
|
+
ActiveSupport::Notifications.subscribed(callback, "sql.active_record", &block)
|
86
|
+
|
87
|
+
assert_not_nil queries.map { |x| x.strip.gsub(/\s+/, ' ') }.
|
88
|
+
find { |x| x == sql.strip.gsub(/\s+/, ' ') }
|
89
|
+
end
|
90
|
+
|
91
|
+
def assert_rendered(options = {}, message = nil)
|
92
|
+
options = case options
|
93
|
+
when NilClass, Regexp, String, Symbol
|
94
|
+
{ layout: options }
|
95
|
+
when Hash
|
96
|
+
options
|
97
|
+
else
|
98
|
+
raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
|
99
|
+
end
|
100
|
+
|
101
|
+
options.assert_valid_keys(:layout, :partial, :count, :format, :handler)
|
102
|
+
|
103
|
+
if expected_layout = options[:layout]
|
104
|
+
case expected_layout
|
105
|
+
when String, Symbol
|
106
|
+
msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
|
107
|
+
expected_layout, @layouts.keys)
|
108
|
+
assert_includes @layouts.keys, expected_layout.to_s, msg
|
109
|
+
|
110
|
+
key = expected_layout.to_s
|
111
|
+
value = @layouts[key]
|
112
|
+
|
113
|
+
if expected_count = options[:count]
|
114
|
+
actual_count = value[:count]
|
115
|
+
msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
|
116
|
+
expected_partial, expected_count, actual_count)
|
117
|
+
assert_equal expected_count, actual_count, msg
|
118
|
+
end
|
119
|
+
|
120
|
+
if expected_format = options[:format]
|
121
|
+
actual_format = value[:format]
|
122
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
123
|
+
expected_partial, expected_format, actual_format)
|
124
|
+
assert_equal expected_format, actual_format, msg
|
125
|
+
end
|
126
|
+
|
127
|
+
if expected_handler = options[:handler]
|
128
|
+
actual_handler = value[:handler]
|
129
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
130
|
+
expected_partial, expected_handler, actual_handler)
|
131
|
+
assert_equal expected_handler, actual_handler, msg
|
132
|
+
end
|
133
|
+
when Regexp
|
134
|
+
msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
|
135
|
+
expected_layout, @layouts.keys)
|
136
|
+
assert(@layouts.keys.any? {|l| l =~ expected_layout }, msg)
|
137
|
+
|
138
|
+
key = @layouts.keys.find {|l| l =~ expected_layout }
|
139
|
+
value = @layouts[key]
|
140
|
+
|
141
|
+
if expected_count = options[:count]
|
142
|
+
actual_count = value[:count]
|
143
|
+
msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
|
144
|
+
expected_partial, expected_count, actual_count)
|
145
|
+
assert_equal expected_count, actual_count, msg
|
146
|
+
end
|
147
|
+
|
148
|
+
if expected_format = options[:format]
|
149
|
+
actual_format = value[:format]
|
150
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
151
|
+
expected_partial, expected_format, actual_format)
|
152
|
+
assert_equal expected_format, actual_format, msg
|
153
|
+
end
|
154
|
+
|
155
|
+
if expected_handler = options[:handler]
|
156
|
+
actual_handler = value[:handler]
|
157
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
158
|
+
expected_partial, expected_handler, actual_handler)
|
159
|
+
assert_equal expected_handler, actual_handler, msg
|
160
|
+
end
|
161
|
+
when nil, false
|
162
|
+
assert(@layouts.empty?, msg)
|
163
|
+
end
|
164
|
+
elsif expected_partial = options[:partial]
|
165
|
+
case expected_partial
|
166
|
+
when String, Symbol
|
167
|
+
msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
|
168
|
+
expected_partial, @partials.keys)
|
169
|
+
assert_includes @partials.keys, expected_partial.to_s, msg
|
170
|
+
|
171
|
+
key = expected_partial.to_s
|
172
|
+
value = @partials[key]
|
173
|
+
|
174
|
+
if expected_count = options[:count]
|
175
|
+
actual_count = value[:count]
|
176
|
+
msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
|
177
|
+
expected_partial, expected_count, actual_count)
|
178
|
+
assert_equal expected_count, actual_count, msg
|
179
|
+
end
|
180
|
+
|
181
|
+
if expected_format = options[:format]
|
182
|
+
actual_format = value[:format]
|
183
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
184
|
+
expected_partial, expected_format, actual_format)
|
185
|
+
assert_equal expected_format, actual_format, msg
|
186
|
+
end
|
187
|
+
|
188
|
+
if expected_handler = options[:handler]
|
189
|
+
actual_handler = value[:handler]
|
190
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
191
|
+
expected_partial, expected_handler, actual_handler)
|
192
|
+
assert_equal expected_handler, actual_handler, msg
|
193
|
+
end
|
194
|
+
when Regexp
|
195
|
+
msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
|
196
|
+
expected_partial, @partials.keys)
|
197
|
+
assert(@partials.keys.any? {|l| l =~ expected_partial }, msg)
|
198
|
+
|
199
|
+
key = @partials.keys.find {|l| l =~ expected_partial }
|
200
|
+
value = @partials[key]
|
201
|
+
|
202
|
+
if expected_count = options[:count]
|
203
|
+
actual_count = value[:count]
|
204
|
+
msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
|
205
|
+
expected_partial, expected_count, actual_count)
|
206
|
+
assert_equal expected_count, actual_count, msg
|
207
|
+
end
|
208
|
+
|
209
|
+
if expected_format = options[:format]
|
210
|
+
actual_format = value[:format]
|
211
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
212
|
+
expected_partial, expected_format, actual_format)
|
213
|
+
assert_equal expected_format, actual_format, msg
|
214
|
+
end
|
215
|
+
|
216
|
+
if expected_handler = options[:handler]
|
217
|
+
actual_handler = value[:handler]
|
218
|
+
msg = message || sprintf("expecting %s to be rendered as %s but rendered as %s",
|
219
|
+
expected_partial, expected_handler, actual_handler)
|
220
|
+
assert_equal expected_handler, actual_handler, msg
|
221
|
+
end
|
222
|
+
when nil, false
|
223
|
+
assert(@partials.empty?, msg)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
class ActionController::TestCase
|
231
|
+
|
232
|
+
def assigns(key = nil)
|
233
|
+
assigns = {}.with_indifferent_access
|
234
|
+
@controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
|
235
|
+
key.nil? ? assigns : assigns[key]
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|