upgrow 0.0.2 → 0.0.3
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/Rakefile +1 -1
- data/lib/upgrow.rb +2 -8
- data/lib/upgrow/action.rb +66 -16
- data/lib/upgrow/actions.rb +31 -0
- data/lib/upgrow/active_record_adapter.rb +24 -15
- data/lib/upgrow/active_record_schema.rb +63 -0
- data/lib/upgrow/basic_model.rb +64 -0
- data/lib/upgrow/basic_repository.rb +49 -22
- data/lib/upgrow/error.rb +19 -0
- data/lib/upgrow/immutable_object.rb +26 -21
- data/lib/upgrow/input.rb +7 -0
- data/lib/upgrow/model.rb +12 -12
- data/lib/upgrow/model_schema.rb +31 -0
- data/lib/upgrow/repository.rb +3 -0
- data/lib/upgrow/result.rb +18 -55
- data/lib/upgrow/schema.rb +33 -0
- data/test/application_system_test_case.rb +11 -0
- data/test/dummy/app/actions/application_action.rb +10 -0
- data/test/dummy/app/actions/articles/create_action.rb +15 -0
- data/test/dummy/app/actions/articles/destroy_action.rb +9 -0
- data/test/dummy/app/actions/articles/edit_action.rb +12 -0
- data/test/dummy/app/actions/articles/index_action.rb +11 -0
- data/test/dummy/app/actions/articles/new_action.rb +8 -0
- data/test/dummy/app/actions/articles/show_action.rb +11 -0
- data/test/dummy/app/actions/articles/update_action.rb +15 -0
- data/test/dummy/app/actions/comments/create_action.rb +15 -0
- data/test/dummy/app/actions/comments/destroy_action.rb +9 -0
- data/test/dummy/app/actions/comments/new_action.rb +8 -0
- data/test/dummy/app/actions/sessions/create_action.rb +23 -0
- data/test/dummy/app/actions/sessions/destroy_action.rb +6 -0
- data/test/dummy/app/actions/sessions/new_action.rb +8 -0
- data/test/dummy/app/actions/user_action.rb +10 -0
- data/test/dummy/app/actions/users/create_action.rb +13 -0
- data/test/dummy/app/actions/users/new_action.rb +8 -0
- data/test/dummy/app/controllers/application_controller.rb +10 -0
- data/test/dummy/app/controllers/articles_controller.rb +32 -28
- data/test/dummy/app/controllers/comments_controller.rb +41 -0
- data/test/dummy/app/controllers/sessions_controller.rb +34 -0
- data/test/dummy/app/controllers/users_controller.rb +29 -0
- data/test/dummy/app/helpers/application_helper.rb +27 -3
- data/test/dummy/app/helpers/users_helper.rb +15 -0
- data/test/dummy/app/inputs/article_input.rb +3 -0
- data/test/dummy/app/inputs/comment_input.rb +11 -0
- data/test/dummy/app/inputs/session_input.rb +9 -0
- data/test/dummy/app/inputs/user_input.rb +9 -0
- data/test/dummy/app/models/article.rb +0 -2
- data/test/dummy/app/models/comment.rb +4 -0
- data/test/dummy/app/models/user.rb +4 -0
- data/test/dummy/app/records/article_record.rb +2 -0
- data/test/dummy/app/records/comment_record.rb +7 -0
- data/test/dummy/app/records/user_record.rb +9 -0
- data/test/dummy/app/repositories/article_repository.rb +26 -0
- data/test/dummy/app/repositories/comment_repository.rb +3 -0
- data/test/dummy/app/repositories/user_repository.rb +12 -0
- data/test/dummy/config/routes.rb +6 -1
- data/test/dummy/db/migrate/20210320140432_create_comments.rb +12 -0
- data/test/dummy/db/migrate/20210409164927_create_users.rb +22 -0
- data/test/dummy/db/schema.rb +24 -1
- data/test/system/articles_test.rb +87 -29
- data/test/system/comments_test.rb +81 -0
- data/test/system/guest_user_test.rb +14 -0
- data/test/system/sign_in_test.rb +57 -0
- data/test/system/sign_out_test.rb +19 -0
- data/test/system/sign_up_test.rb +38 -0
- data/test/test_helper.rb +6 -1
- data/test/upgrow/action_test.rb +101 -9
- data/test/upgrow/actions_test.rb +24 -0
- data/test/upgrow/active_record_adapter_test.rb +12 -17
- data/test/upgrow/active_record_schema_test.rb +92 -0
- data/test/upgrow/basic_model_test.rb +95 -0
- data/test/upgrow/basic_repository_test.rb +48 -27
- data/test/upgrow/immutable_object_test.rb +43 -7
- data/test/upgrow/input_test.rb +19 -1
- data/test/upgrow/model_schema_test.rb +44 -0
- data/test/upgrow/model_test.rb +48 -11
- data/test/upgrow/result_test.rb +19 -64
- data/test/upgrow/schema_test.rb +44 -0
- metadata +128 -50
- data/test/dummy/app/actions/create_article_action.rb +0 -13
- data/test/dummy/app/actions/delete_article_action.rb +0 -7
- data/test/dummy/app/actions/edit_article_action.rb +0 -10
- data/test/dummy/app/actions/list_articles_action.rb +0 -8
- data/test/dummy/app/actions/show_article_action.rb +0 -10
- data/test/dummy/app/actions/update_article_action.rb +0 -13
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
module Upgrow
|
6
|
+
class BasicModelTest < ActiveSupport::TestCase
|
7
|
+
class SampleModel < BasicModel
|
8
|
+
attribute :title
|
9
|
+
attribute :body
|
10
|
+
|
11
|
+
belongs_to :user
|
12
|
+
end
|
13
|
+
|
14
|
+
class SubSampleModel < SampleModel
|
15
|
+
has_many :tags
|
16
|
+
end
|
17
|
+
|
18
|
+
setup do
|
19
|
+
@original_schema = BasicModel.schema.dup
|
20
|
+
end
|
21
|
+
|
22
|
+
teardown do
|
23
|
+
BasicModel.schema = @original_schema
|
24
|
+
end
|
25
|
+
|
26
|
+
test '.schema includes ID by default' do
|
27
|
+
assert_equal [:id, :title, :body], SampleModel.schema.attribute_names
|
28
|
+
end
|
29
|
+
|
30
|
+
test '.schema does not have associations by default' do
|
31
|
+
assert_empty BasicModel.schema.association_names
|
32
|
+
end
|
33
|
+
|
34
|
+
test '.schema includes the Model associations' do
|
35
|
+
assert_equal [:user], SampleModel.schema.association_names
|
36
|
+
assert_equal [:user, :tags], SubSampleModel.schema.association_names
|
37
|
+
end
|
38
|
+
|
39
|
+
test '.has_many defines an association in the Schema' do
|
40
|
+
BasicModel.has_many(:comments)
|
41
|
+
assert_equal [:comments], BasicModel.schema.association_names
|
42
|
+
end
|
43
|
+
|
44
|
+
test '.belongs_to defines an association in the Schema' do
|
45
|
+
BasicModel.belongs_to(:author)
|
46
|
+
assert_equal [:author], BasicModel.schema.association_names
|
47
|
+
end
|
48
|
+
|
49
|
+
test '.new requires all attributes' do
|
50
|
+
error = assert_raises(KeyError) do
|
51
|
+
SampleModel.new(title: 'volmer', id: 1)
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_equal 'key not found: :body', error.message
|
55
|
+
end
|
56
|
+
|
57
|
+
test '.new optionally accepts associations' do
|
58
|
+
model = SampleModel.new(
|
59
|
+
title: 'volmer',
|
60
|
+
body: 'My long body',
|
61
|
+
id: 1,
|
62
|
+
user: :my_user
|
63
|
+
)
|
64
|
+
|
65
|
+
assert_equal :my_user, model.user
|
66
|
+
end
|
67
|
+
|
68
|
+
test '#respond_to? is true for association readers' do
|
69
|
+
model = SubSampleModel.new(id: 1, title: 'volmer', body: 'hello')
|
70
|
+
|
71
|
+
assert model.respond_to?(:user)
|
72
|
+
assert model.respond_to?(:tags)
|
73
|
+
end
|
74
|
+
|
75
|
+
test 'association reader raises Association Not Loaded Error for an association that was not loaded' do
|
76
|
+
model = SampleModel.new(
|
77
|
+
title: 'volmer',
|
78
|
+
body: 'My long body',
|
79
|
+
id: 1,
|
80
|
+
)
|
81
|
+
|
82
|
+
assert_raises(Model::AssociationNotLoadedError) { model.user }
|
83
|
+
end
|
84
|
+
|
85
|
+
test 'attribute readers work when association is not loaded' do
|
86
|
+
model = SampleModel.new(
|
87
|
+
title: 'volmer',
|
88
|
+
body: 'My long body',
|
89
|
+
id: 1,
|
90
|
+
)
|
91
|
+
|
92
|
+
assert_equal 'volmer', model.title
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -4,36 +4,48 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
module Upgrow
|
6
6
|
class BasicRepositoryTest < ActiveSupport::TestCase
|
7
|
-
class User <
|
7
|
+
class User < BasicModel; end
|
8
|
+
|
9
|
+
class Car < BasicModel
|
10
|
+
attribute :wheels
|
11
|
+
end
|
8
12
|
|
9
13
|
class UserRepository < BasicRepository; end
|
10
14
|
|
11
15
|
class NoModelRepository < BasicRepository; end
|
12
16
|
|
13
17
|
setup do
|
14
|
-
|
15
|
-
|
18
|
+
@original_base = UserRepository.base
|
19
|
+
@original_model_class = UserRepository.model_class
|
16
20
|
@repository = UserRepository.new
|
17
21
|
end
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
teardown do
|
24
|
+
UserRepository.base = @original_base
|
25
|
+
UserRepository.model_class = @original_model_class
|
26
|
+
end
|
27
|
+
|
28
|
+
test '.base is nil by default' do
|
29
|
+
assert_nil UserRepository.base
|
30
|
+
end
|
21
31
|
|
22
|
-
|
23
|
-
|
32
|
+
test '.base can be set' do
|
33
|
+
UserRepository.base = :my_base
|
34
|
+
assert_equal :my_base, UserRepository.base
|
24
35
|
end
|
25
36
|
|
26
|
-
test '.
|
27
|
-
|
37
|
+
test '.model_class is iferred based on the Repository name' do
|
38
|
+
assert_equal User, UserRepository.model_class
|
28
39
|
end
|
29
40
|
|
30
|
-
test '.
|
31
|
-
|
41
|
+
test '.model_class can be set' do
|
42
|
+
UserRepository.model_class = :my_model_class
|
43
|
+
assert_equal :my_model_class, UserRepository.model_class
|
32
44
|
end
|
33
45
|
|
34
|
-
test '.
|
46
|
+
test '.model_class raises a Name Error if the Model class is undefined' do
|
35
47
|
error = assert_raises(NameError) do
|
36
|
-
NoModelRepository.
|
48
|
+
NoModelRepository.model_class
|
37
49
|
end
|
38
50
|
|
39
51
|
assert_includes(
|
@@ -42,32 +54,41 @@ module Upgrow
|
|
42
54
|
)
|
43
55
|
end
|
44
56
|
|
45
|
-
test '
|
46
|
-
|
47
|
-
|
48
|
-
|
57
|
+
test '#base is inferred from the Repository class base' do
|
58
|
+
UserRepository.base = :my_base
|
59
|
+
assert_equal :my_base, UserRepository.new.base
|
60
|
+
end
|
61
|
+
|
62
|
+
test '#model_class is inferred from the Repository class Model class' do
|
63
|
+
UserRepository.model_class = :my_model_class
|
64
|
+
assert_equal :my_model_class, UserRepository.new.model_class
|
65
|
+
end
|
66
|
+
|
67
|
+
test '#to_model returns a new Model with the given attributes as keyword arguments' do
|
68
|
+
model = @repository.to_model(id: 1)
|
69
|
+
|
70
|
+
assert_equal 1, model.id
|
71
|
+
end
|
72
|
+
|
73
|
+
test '#to_model accepts a Model class explicitly' do
|
74
|
+
model = @repository.to_model(Car, id: 1, wheels: 4)
|
49
75
|
|
50
76
|
assert_equal 1, model.id
|
51
|
-
assert_equal
|
52
|
-
assert_equal Time.now, model.updated_at
|
77
|
+
assert_equal 4, model.wheels
|
53
78
|
end
|
54
79
|
|
55
|
-
test '
|
56
|
-
args = { id: 1
|
80
|
+
test '#to_model accepts a Hash of Symbols' do
|
81
|
+
args = { id: 1 }
|
57
82
|
model = @repository.to_model(args)
|
58
83
|
|
59
84
|
assert_equal 1, model.id
|
60
|
-
assert_equal Time.now, model.created_at
|
61
|
-
assert_equal Time.now, model.updated_at
|
62
85
|
end
|
63
86
|
|
64
|
-
test '
|
65
|
-
args = { 'id' => 1
|
87
|
+
test '#to_model accepts a Hash of Strings' do
|
88
|
+
args = { 'id' => 1 }
|
66
89
|
model = @repository.to_model(args)
|
67
90
|
|
68
91
|
assert_equal 1, model.id
|
69
|
-
assert_equal Time.now, model.created_at
|
70
|
-
assert_equal Time.now, model.updated_at
|
71
92
|
end
|
72
93
|
end
|
73
94
|
end
|
@@ -13,12 +13,26 @@ module Upgrow
|
|
13
13
|
attribute :name
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
setup do
|
17
|
+
@original_schema = Sample.schema
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
teardown do
|
21
|
+
Sample.schema = @original_schema
|
22
|
+
end
|
23
|
+
|
24
|
+
test '.schema is empty by default' do
|
25
|
+
assert_empty ImmutableObject.schema.attribute_names
|
26
|
+
end
|
27
|
+
|
28
|
+
test '.schema can be set' do
|
29
|
+
Sample.schema = :my_schema
|
30
|
+
|
31
|
+
assert_equal :my_schema, Sample.schema
|
32
|
+
end
|
33
|
+
|
34
|
+
test '.schema contains all declared attributes' do
|
35
|
+
assert_equal [:title, :body, :name], SubSample.schema.attribute_names
|
22
36
|
end
|
23
37
|
|
24
38
|
test '.new creates a frozen instance with the given attributes' do
|
@@ -29,7 +43,7 @@ module Upgrow
|
|
29
43
|
assert sample.frozen?
|
30
44
|
end
|
31
45
|
|
32
|
-
test 'it does not allow
|
46
|
+
test 'it does not allow attributes to be mutated' do
|
33
47
|
sample = Sample.new(title: 'volmer', body: 'hello')
|
34
48
|
|
35
49
|
refute sample.respond_to?(:title=)
|
@@ -44,17 +58,39 @@ module Upgrow
|
|
44
58
|
assert_equal 'Unknown attribute [:fake]', error.message
|
45
59
|
end
|
46
60
|
|
47
|
-
test '.new
|
61
|
+
test '.new allows inherited attributes' do
|
48
62
|
sub_sample = SubSample.new(title: 'volmer', body: 'hello', name: 'rafael')
|
49
63
|
assert_equal 'volmer', sub_sample.title
|
50
64
|
assert_equal 'hello', sub_sample.body
|
51
65
|
assert_equal 'rafael', sub_sample.name
|
52
66
|
end
|
53
67
|
|
54
|
-
test '
|
68
|
+
test '.new allows omitting attributes' do
|
69
|
+
sub_sample = SubSample.new(title: 'volmer')
|
70
|
+
assert_equal 'volmer', sub_sample.title
|
71
|
+
assert_nil sub_sample.body
|
72
|
+
assert_nil sub_sample.name
|
73
|
+
end
|
74
|
+
|
75
|
+
test '#respond_to? is true for all attribute readers' do
|
76
|
+
sub_sample = SubSample.new(title: 'volmer')
|
77
|
+
|
78
|
+
assert sub_sample.respond_to?(:title)
|
79
|
+
assert sub_sample.respond_to?(:body)
|
80
|
+
assert sub_sample.respond_to?(:name)
|
81
|
+
end
|
82
|
+
|
83
|
+
test '#attributes returns the collection of frozen attributes' do
|
55
84
|
sample = Sample.new(title: 'volmer', body: 'hello')
|
56
85
|
|
57
86
|
assert_equal({ title: 'volmer', body: 'hello' }, sample.attributes)
|
87
|
+
assert sample.attributes.frozen?
|
88
|
+
end
|
89
|
+
|
90
|
+
test '#attributes returns attributes that were omitted' do
|
91
|
+
sample = Sample.new
|
92
|
+
|
93
|
+
assert_equal({ title: nil, body: nil }, sample.attributes)
|
58
94
|
end
|
59
95
|
end
|
60
96
|
end
|
data/test/upgrow/input_test.rb
CHANGED
@@ -12,7 +12,7 @@ module Upgrow
|
|
12
12
|
validates :title, presence: true
|
13
13
|
end
|
14
14
|
|
15
|
-
test '#errors is
|
15
|
+
test '#errors is empty' do
|
16
16
|
input = Input.new
|
17
17
|
errors = input.errors
|
18
18
|
assert_empty errors
|
@@ -61,5 +61,23 @@ module Upgrow
|
|
61
61
|
input = SampleInput.new
|
62
62
|
refute_predicate input, :valid?
|
63
63
|
end
|
64
|
+
|
65
|
+
test '#errors is empty when validation is successful' do
|
66
|
+
input = SampleInput.new(title: 'volmer')
|
67
|
+
assert_predicate input, :valid?
|
68
|
+
assert_empty input.errors
|
69
|
+
end
|
70
|
+
|
71
|
+
test '#errors is populated when validation fails' do
|
72
|
+
input = SampleInput.new
|
73
|
+
refute_predicate input, :valid?
|
74
|
+
assert_predicate input.errors, :one?
|
75
|
+
|
76
|
+
error = input.errors.first
|
77
|
+
|
78
|
+
assert_equal :title, error.attribute
|
79
|
+
assert_equal :blank, error.type
|
80
|
+
assert_equal "Title can't be blank", error.full_message
|
81
|
+
end
|
64
82
|
end
|
65
83
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
module Upgrow
|
6
|
+
class ModelSchemaTest < ActiveSupport::TestCase
|
7
|
+
setup do
|
8
|
+
@schema = ModelSchema.new
|
9
|
+
end
|
10
|
+
|
11
|
+
test '#association_names is empty by default' do
|
12
|
+
assert_empty @schema.attribute_names
|
13
|
+
end
|
14
|
+
|
15
|
+
test '#association_names returns the defined associations' do
|
16
|
+
@schema.association(:user)
|
17
|
+
@schema.association(:tags)
|
18
|
+
|
19
|
+
assert_equal [:user, :tags], @schema.association_names
|
20
|
+
end
|
21
|
+
|
22
|
+
test '#association defines an association' do
|
23
|
+
@schema.association(:user)
|
24
|
+
|
25
|
+
assert_equal [:user], @schema.association_names
|
26
|
+
end
|
27
|
+
|
28
|
+
test '#association does not define the same association twice' do
|
29
|
+
@schema.association(:user)
|
30
|
+
@schema.association(:user)
|
31
|
+
|
32
|
+
assert_equal [:user], @schema.association_names
|
33
|
+
end
|
34
|
+
|
35
|
+
test '#dup creates a Schema with independent association names' do
|
36
|
+
@schema.association(:user)
|
37
|
+
new_schema = @schema.dup
|
38
|
+
new_schema.association(:tags)
|
39
|
+
|
40
|
+
assert_equal [:user], @schema.association_names
|
41
|
+
assert_equal [:user, :tags], new_schema.association_names
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/test/upgrow/model_test.rb
CHANGED
@@ -2,26 +2,63 @@
|
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
|
+
require 'upgrow/model'
|
6
|
+
|
5
7
|
module Upgrow
|
6
8
|
class ModelTest < ActiveSupport::TestCase
|
7
9
|
class SampleModel < Model
|
8
|
-
attribute :title
|
9
|
-
attribute :body
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
class SubSampleModel < SampleModel
|
13
|
+
end
|
14
|
+
|
15
|
+
class SampleModelWithAttribute < Model
|
16
|
+
attribute :phone
|
17
|
+
end
|
18
|
+
|
19
|
+
class SampleModelRecord
|
20
|
+
def self.attribute_names
|
21
|
+
['id', 'name']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class SubSampleModelRecord
|
26
|
+
def self.attribute_names
|
27
|
+
['email']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class SampleModelWithAttributeRecord
|
32
|
+
def self.attribute_names
|
33
|
+
['id']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class OrphanedModel < Model
|
38
|
+
end
|
39
|
+
|
40
|
+
test '.schema is inferred from the Active Record with the Model name' do
|
41
|
+
assert_equal [:id, :name], SampleModel.schema.attribute_names
|
42
|
+
end
|
43
|
+
|
44
|
+
test '.schema is populated with inherited attributes' do
|
45
|
+
assert_equal [:email, :id, :name], SubSampleModel.schema.attribute_names
|
46
|
+
end
|
47
|
+
|
48
|
+
test '.schema includes explicit attributes as well as Active Record attributes' do
|
49
|
+
assert_equal [:id, :phone],
|
50
|
+
SampleModelWithAttribute.schema.attribute_names
|
15
51
|
end
|
16
52
|
|
17
|
-
test '.new
|
18
|
-
error = assert_raises(
|
19
|
-
|
20
|
-
title: 'volmer', id: 1, created_at: Time.now, updated_at: Time.now
|
21
|
-
)
|
53
|
+
test '.new raises a Name Error if the Record class is undefined' do
|
54
|
+
error = assert_raises(NameError) do
|
55
|
+
OrphanedModel.new
|
22
56
|
end
|
23
57
|
|
24
|
-
|
58
|
+
assert_includes(
|
59
|
+
error.message,
|
60
|
+
'uninitialized constant Upgrow::ModelTest::OrphanedModelRecord'
|
61
|
+
)
|
25
62
|
end
|
26
63
|
end
|
27
64
|
end
|