restorm 1.0.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 +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +232 -0
- data/.ruby-version +1 -0
- data/.travis.yml +55 -0
- data/.yardopts +2 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +10 -0
- data/HER_README.md +1065 -0
- data/LICENSE +7 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/UPGRADE.md +101 -0
- data/gemfiles/Gemfile.activemodel-4.2 +6 -0
- data/gemfiles/Gemfile.activemodel-5.0 +6 -0
- data/gemfiles/Gemfile.activemodel-5.1 +6 -0
- data/gemfiles/Gemfile.activemodel-5.2 +6 -0
- data/gemfiles/Gemfile.faraday-1.0 +6 -0
- data/lib/restorm/api.rb +121 -0
- data/lib/restorm/collection.rb +13 -0
- data/lib/restorm/errors.rb +29 -0
- data/lib/restorm/json_api/model.rb +42 -0
- data/lib/restorm/middleware/accept_json.rb +18 -0
- data/lib/restorm/middleware/first_level_parse_json.rb +37 -0
- data/lib/restorm/middleware/json_api_parser.rb +37 -0
- data/lib/restorm/middleware/parse_json.rb +22 -0
- data/lib/restorm/middleware/second_level_parse_json.rb +37 -0
- data/lib/restorm/middleware.rb +12 -0
- data/lib/restorm/model/associations/association.rb +128 -0
- data/lib/restorm/model/associations/association_proxy.rb +44 -0
- data/lib/restorm/model/associations/belongs_to_association.rb +95 -0
- data/lib/restorm/model/associations/has_many_association.rb +100 -0
- data/lib/restorm/model/associations/has_one_association.rb +79 -0
- data/lib/restorm/model/associations.rb +141 -0
- data/lib/restorm/model/attributes.rb +322 -0
- data/lib/restorm/model/base.rb +33 -0
- data/lib/restorm/model/deprecated_methods.rb +61 -0
- data/lib/restorm/model/http.rb +119 -0
- data/lib/restorm/model/introspection.rb +67 -0
- data/lib/restorm/model/nested_attributes.rb +45 -0
- data/lib/restorm/model/orm.rb +299 -0
- data/lib/restorm/model/parse.rb +223 -0
- data/lib/restorm/model/paths.rb +125 -0
- data/lib/restorm/model/relation.rb +209 -0
- data/lib/restorm/model.rb +75 -0
- data/lib/restorm/version.rb +3 -0
- data/lib/restorm.rb +19 -0
- data/restorm.gemspec +29 -0
- data/spec/api_spec.rb +120 -0
- data/spec/collection_spec.rb +41 -0
- data/spec/json_api/model_spec.rb +169 -0
- data/spec/middleware/accept_json_spec.rb +11 -0
- data/spec/middleware/first_level_parse_json_spec.rb +63 -0
- data/spec/middleware/json_api_parser_spec.rb +52 -0
- data/spec/middleware/second_level_parse_json_spec.rb +35 -0
- data/spec/model/associations/association_proxy_spec.rb +29 -0
- data/spec/model/associations_spec.rb +911 -0
- data/spec/model/attributes_spec.rb +354 -0
- data/spec/model/callbacks_spec.rb +176 -0
- data/spec/model/dirty_spec.rb +133 -0
- data/spec/model/http_spec.rb +201 -0
- data/spec/model/introspection_spec.rb +81 -0
- data/spec/model/nested_attributes_spec.rb +135 -0
- data/spec/model/orm_spec.rb +704 -0
- data/spec/model/parse_spec.rb +520 -0
- data/spec/model/paths_spec.rb +348 -0
- data/spec/model/relation_spec.rb +247 -0
- data/spec/model/validations_spec.rb +43 -0
- data/spec/model_spec.rb +45 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/model_macros.rb +36 -0
- data/spec/support/macros/request_macros.rb +27 -0
- metadata +203 -0
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
4
|
+
|
5
|
+
describe Restorm::Model::HTTP do
|
6
|
+
context "binding a model with an API" do
|
7
|
+
let(:api1) { Restorm::API.new url: "https://api1.example.com" }
|
8
|
+
let(:api2) { Restorm::API.new url: "https://api2.example.com" }
|
9
|
+
|
10
|
+
before do
|
11
|
+
spawn_model("Foo::User")
|
12
|
+
spawn_model("Foo::Comment")
|
13
|
+
Restorm::API.setup url: "https://api.example.com"
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when binding a model to its superclass' her_api" do
|
17
|
+
before do
|
18
|
+
spawn_model "Foo::Superclass"
|
19
|
+
Foo::Superclass.uses_api api1
|
20
|
+
Foo::Subclass = Class.new(Foo::Superclass)
|
21
|
+
end
|
22
|
+
|
23
|
+
specify { expect(Foo::Subclass.her_api).to eq(Foo::Superclass.her_api) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when changing her_api without changing the parent class' restorm_api" do
|
27
|
+
before do
|
28
|
+
spawn_model "Foo::Superclass"
|
29
|
+
Foo::Subclass = Class.new(Foo::Superclass)
|
30
|
+
Foo::Superclass.uses_api api1
|
31
|
+
Foo::Subclass.uses_api api2
|
32
|
+
end
|
33
|
+
|
34
|
+
specify { expect(Foo::Subclass.her_api).not_to eq(Foo::Superclass.restorm_api) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "making HTTP requests" do
|
39
|
+
before do
|
40
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
41
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
42
|
+
builder.use Faraday::Request::UrlEncoded
|
43
|
+
builder.adapter :test do |stub|
|
44
|
+
stub.get("/users") { [200, {}, [{ id: 1 }].to_json] }
|
45
|
+
stub.get("/users/1") { [200, {}, { id: 1 }.to_json] }
|
46
|
+
stub.get("/users/popular") do |env|
|
47
|
+
if env[:params]["page"] == "2"
|
48
|
+
[200, {}, [{ id: 3 }, { id: 4 }].to_json]
|
49
|
+
else
|
50
|
+
[200, {}, [{ id: 1 }, { id: 2 }].to_json]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
spawn_model "Foo::User"
|
57
|
+
end
|
58
|
+
|
59
|
+
describe :get do
|
60
|
+
subject { Foo::User.get(:popular) }
|
61
|
+
|
62
|
+
describe "#length" do
|
63
|
+
subject { super().length }
|
64
|
+
it { is_expected.to eq(2) }
|
65
|
+
end
|
66
|
+
specify { expect(subject.first.id).to eq(1) }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe :get_raw do
|
70
|
+
context "with a block" do
|
71
|
+
specify do
|
72
|
+
Foo::User.get_raw("/users") do |parsed_data, _response|
|
73
|
+
expect(parsed_data[:data]).to eq([{ id: 1 }])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with a return value" do
|
79
|
+
subject { Foo::User.get_raw("/users") }
|
80
|
+
specify { expect(subject[:parsed_data][:data]).to eq([{ id: 1 }]) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe :get_collection do
|
85
|
+
context "with a String path" do
|
86
|
+
subject { Foo::User.get_collection("/users/popular") }
|
87
|
+
|
88
|
+
describe "#length" do
|
89
|
+
subject { super().length }
|
90
|
+
it { is_expected.to eq(2) }
|
91
|
+
end
|
92
|
+
specify { expect(subject.first.id).to eq(1) }
|
93
|
+
end
|
94
|
+
|
95
|
+
context "with a Symbol" do
|
96
|
+
subject { Foo::User.get_collection(:popular) }
|
97
|
+
|
98
|
+
describe "#length" do
|
99
|
+
subject { super().length }
|
100
|
+
it { is_expected.to eq(2) }
|
101
|
+
end
|
102
|
+
specify { expect(subject.first.id).to eq(1) }
|
103
|
+
end
|
104
|
+
|
105
|
+
context "with extra parameters" do
|
106
|
+
subject { Foo::User.get_collection(:popular, page: 2) }
|
107
|
+
|
108
|
+
describe "#length" do
|
109
|
+
subject { super().length }
|
110
|
+
it { is_expected.to eq(2) }
|
111
|
+
end
|
112
|
+
specify { expect(subject.first.id).to eq(3) }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe :get_resource do
|
117
|
+
context "with a String path" do
|
118
|
+
subject { Foo::User.get_resource("/users/1") }
|
119
|
+
|
120
|
+
describe "#id" do
|
121
|
+
subject { super().id }
|
122
|
+
it { is_expected.to eq(1) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "with a Symbol" do
|
127
|
+
subject { Foo::User.get_resource(:"1") }
|
128
|
+
|
129
|
+
describe "#id" do
|
130
|
+
subject { super().id }
|
131
|
+
it { is_expected.to eq(1) }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe :get_raw do
|
137
|
+
specify do
|
138
|
+
Foo::User.get_raw(:popular) do |parsed_data, _response|
|
139
|
+
expect(parsed_data[:data]).to eq([{ id: 1 }, { id: 2 }])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "setting custom HTTP requests" do
|
146
|
+
before do
|
147
|
+
Restorm::API.setup url: "https://api.example.com" do |connection|
|
148
|
+
connection.use Restorm::Middleware::FirstLevelParseJSON
|
149
|
+
connection.adapter :test do |stub|
|
150
|
+
stub.get("/users/popular") { [200, {}, [{ id: 1 }, { id: 2 }].to_json] }
|
151
|
+
stub.post("/users/from_default") { [200, {}, { id: 4 }.to_json] }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
spawn_model "Foo::User"
|
156
|
+
end
|
157
|
+
|
158
|
+
subject { Foo::User }
|
159
|
+
|
160
|
+
describe :custom_get do
|
161
|
+
before do
|
162
|
+
Foo::User.custom_get :popular, :recent
|
163
|
+
end
|
164
|
+
|
165
|
+
it { is_expected.to respond_to(:popular) }
|
166
|
+
it { is_expected.to respond_to(:recent) }
|
167
|
+
|
168
|
+
it "makes HTTP request" do
|
169
|
+
expect(Foo::User.popular.length).to be 2
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe :custom_post do
|
174
|
+
before do
|
175
|
+
Foo::User.custom_post :from_default
|
176
|
+
end
|
177
|
+
|
178
|
+
it { is_expected.to respond_to(:from_default) }
|
179
|
+
|
180
|
+
it "makes HTTP request" do
|
181
|
+
user = Foo::User.from_default(name: "Tobias Fünke")
|
182
|
+
expect(user.id).to be 4
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "with options" do
|
187
|
+
before do
|
188
|
+
allow(Foo::User).to receive(:warn)
|
189
|
+
Foo::User.custom_get :popular, foo: "bar"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "issues DEPRECATION warning" do
|
193
|
+
expect(Foo::User).to have_received(:warn).with("[DEPRECATION] options for custom request methods are deprecated and will be removed on or after January 2020.")
|
194
|
+
end
|
195
|
+
|
196
|
+
it "makes HTTP request" do
|
197
|
+
expect(Foo::User.popular.length).to be 2
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
4
|
+
|
5
|
+
describe Restorm::Model::Introspection do
|
6
|
+
context "introspecting a resource" do
|
7
|
+
before do
|
8
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
9
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
10
|
+
builder.use Faraday::Request::UrlEncoded
|
11
|
+
builder.adapter :test do |stub|
|
12
|
+
stub.post("/users") { [200, {}, { id: 1, name: "Tobias Funke" }.to_json] }
|
13
|
+
stub.get("/users/1") { [200, {}, { id: 1, name: "Tobias Funke" }.to_json] }
|
14
|
+
stub.put("/users/1") { [200, {}, { id: 1, name: "Tobias Funke" }.to_json] }
|
15
|
+
stub.delete("/users/1") { [200, {}, { id: 1, name: "Tobias Funke" }.to_json] }
|
16
|
+
stub.get("/projects/1/comments") { [200, {}, [{ id: 1, body: "Hello!" }].to_json] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
spawn_model "Foo::User"
|
21
|
+
spawn_model "Foo::Comment" do
|
22
|
+
collection_path "projects/:project_id/comments"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#inspect" do
|
27
|
+
it "outputs resource attributes for an existing resource" do
|
28
|
+
@user = Foo::User.find(1)
|
29
|
+
expect(["#<Foo::User(users/1) name=\"Tobias Funke\" id=1>", "#<Foo::User(users/1) id=1 name=\"Tobias Funke\">"]).to include(@user.inspect)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "outputs resource attributes for an not-saved-yet resource" do
|
33
|
+
@user = Foo::User.new(name: "Tobias Funke")
|
34
|
+
expect(@user.inspect).to eq("#<Foo::User(users) name=\"Tobias Funke\">")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "outputs resource attributes using getters" do
|
38
|
+
@user = Foo::User.new(name: "Tobias Funke", password: "Funke")
|
39
|
+
@user.instance_eval do
|
40
|
+
def password
|
41
|
+
"filtered"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
expect(@user.inspect).to include("name=\"Tobias Funke\"")
|
45
|
+
expect(@user.inspect).to include("password=\"filtered\"")
|
46
|
+
expect(@user.inspect).not_to include("password=\"Funke\"")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "support dash on attribute" do
|
50
|
+
@user = Foo::User.new(:'life-span' => "3 years")
|
51
|
+
expect(@user.inspect).to include("life-span=\"3 years\"")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#inspect with errors in resource path" do
|
56
|
+
it "prints the resource path as “unknown”" do
|
57
|
+
@comment = Foo::Comment.where(project_id: 1).first
|
58
|
+
path = "<unknown path, missing `project_id`>"
|
59
|
+
expect(["#<Foo::Comment(#{path}) body=\"Hello!\" id=1>", "#<Foo::Comment(#{path}) id=1 body=\"Hello!\">"]).to include(@comment.inspect)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#restorm_nearby_class" do
|
65
|
+
context "for a class inside of a module" do
|
66
|
+
before do
|
67
|
+
spawn_model "Foo::User"
|
68
|
+
spawn_model "Foo::AccessRecord"
|
69
|
+
spawn_model "AccessRecord"
|
70
|
+
spawn_model "Log"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns a sibling class, if found" do
|
74
|
+
expect(Foo::User.restorm_nearby_class("AccessRecord")).to eq(Foo::AccessRecord)
|
75
|
+
expect(AccessRecord.restorm_nearby_class("Log")).to eq(Log)
|
76
|
+
expect(Foo::User.restorm_nearby_class("Log")).to eq(Log)
|
77
|
+
expect { Foo::User.restorm_nearby_class("X") }.to raise_error(NameError)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
4
|
+
|
5
|
+
describe Restorm::Model::NestedAttributes do
|
6
|
+
context "with a belongs_to association" do
|
7
|
+
before do
|
8
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
9
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
10
|
+
builder.use Faraday::Request::UrlEncoded
|
11
|
+
end
|
12
|
+
|
13
|
+
spawn_model "Foo::User" do
|
14
|
+
belongs_to :company, path: "/organizations/:id", foreign_key: :organization_id
|
15
|
+
accepts_nested_attributes_for :company
|
16
|
+
end
|
17
|
+
|
18
|
+
spawn_model "Foo::Company"
|
19
|
+
|
20
|
+
@user_with_data_through_nested_attributes = Foo::User.new name: "Test", company_attributes: { name: "Example Company" }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when child does not yet exist" do
|
24
|
+
it "creates an instance of the associated class" do
|
25
|
+
expect(@user_with_data_through_nested_attributes.company).to be_a(Foo::Company)
|
26
|
+
expect(@user_with_data_through_nested_attributes.company.name).to eq("Example Company")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when child does exist" do
|
31
|
+
it "updates the attributes of the associated object" do
|
32
|
+
@user_with_data_through_nested_attributes.company_attributes = { name: "Fünke's Company" }
|
33
|
+
expect(@user_with_data_through_nested_attributes.company).to be_a(Foo::Company)
|
34
|
+
expect(@user_with_data_through_nested_attributes.company.name).to eq("Fünke's Company")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with a has_one association" do
|
40
|
+
before do
|
41
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
42
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
43
|
+
builder.use Faraday::Request::UrlEncoded
|
44
|
+
end
|
45
|
+
|
46
|
+
spawn_model "Foo::User" do
|
47
|
+
has_one :pet
|
48
|
+
accepts_nested_attributes_for :pet
|
49
|
+
end
|
50
|
+
|
51
|
+
spawn_model "Foo::Pet"
|
52
|
+
|
53
|
+
@user_with_data_through_nested_attributes = Foo::User.new name: "Test", pet_attributes: { name: "Hasi" }
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when child does not yet exist" do
|
57
|
+
it "creates an instance of the associated class" do
|
58
|
+
expect(@user_with_data_through_nested_attributes.pet).to be_a(Foo::Pet)
|
59
|
+
expect(@user_with_data_through_nested_attributes.pet.name).to eq("Hasi")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when child does exist" do
|
64
|
+
it "updates the attributes of the associated object" do
|
65
|
+
@user_with_data_through_nested_attributes.pet_attributes = { name: "Rodriguez" }
|
66
|
+
expect(@user_with_data_through_nested_attributes.pet).to be_a(Foo::Pet)
|
67
|
+
expect(@user_with_data_through_nested_attributes.pet.name).to eq("Rodriguez")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with a has_many association" do
|
73
|
+
before do
|
74
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
75
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
76
|
+
builder.use Faraday::Request::UrlEncoded
|
77
|
+
end
|
78
|
+
|
79
|
+
spawn_model "Foo::User" do
|
80
|
+
has_many :pets
|
81
|
+
accepts_nested_attributes_for :pets
|
82
|
+
end
|
83
|
+
|
84
|
+
spawn_model "Foo::Pet"
|
85
|
+
|
86
|
+
@user_with_data_through_nested_attributes = Foo::User.new name: "Test", pets_attributes: [{ name: "Hasi" }, { name: "Rodriguez" }]
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when children do not yet exist" do
|
90
|
+
it "creates an instance of the associated class" do
|
91
|
+
expect(@user_with_data_through_nested_attributes.pets.length).to eq(2)
|
92
|
+
expect(@user_with_data_through_nested_attributes.pets[0]).to be_a(Foo::Pet)
|
93
|
+
expect(@user_with_data_through_nested_attributes.pets[1]).to be_a(Foo::Pet)
|
94
|
+
expect(@user_with_data_through_nested_attributes.pets[0].name).to eq("Hasi")
|
95
|
+
expect(@user_with_data_through_nested_attributes.pets[1].name).to eq("Rodriguez")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "with a has_many association as a Hash" do
|
101
|
+
before do
|
102
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
103
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
104
|
+
builder.use Faraday::Request::UrlEncoded
|
105
|
+
end
|
106
|
+
|
107
|
+
spawn_model "Foo::User" do
|
108
|
+
has_many :pets
|
109
|
+
accepts_nested_attributes_for :pets
|
110
|
+
end
|
111
|
+
|
112
|
+
spawn_model "Foo::Pet"
|
113
|
+
|
114
|
+
@user_with_data_through_nested_attributes_as_hash = Foo::User.new name: "Test", pets_attributes: { "0" => { name: "Hasi" }, "1" => { name: "Rodriguez" } }
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when children do not yet exist" do
|
118
|
+
it "creates an instance of the associated class" do
|
119
|
+
expect(@user_with_data_through_nested_attributes_as_hash.pets.length).to eq(2)
|
120
|
+
expect(@user_with_data_through_nested_attributes_as_hash.pets[0]).to be_a(Foo::Pet)
|
121
|
+
expect(@user_with_data_through_nested_attributes_as_hash.pets[1]).to be_a(Foo::Pet)
|
122
|
+
expect(@user_with_data_through_nested_attributes_as_hash.pets[0].name).to eq("Hasi")
|
123
|
+
expect(@user_with_data_through_nested_attributes_as_hash.pets[1].name).to eq("Rodriguez")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "with an unknown association" do
|
129
|
+
it "raises an error" do
|
130
|
+
expect do
|
131
|
+
spawn_model("Foo::User") { accepts_nested_attributes_for :company }
|
132
|
+
end.to raise_error(Restorm::Errors::AssociationUnknownError, "Unknown association name :company")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|