upgrow 0.0.1 → 0.0.2

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -12
  3. data/Rakefile +8 -4
  4. data/lib/upgrow.rb +13 -2
  5. data/lib/upgrow/action.rb +54 -0
  6. data/lib/upgrow/active_record_adapter.rb +73 -0
  7. data/lib/upgrow/basic_repository.rb +45 -0
  8. data/lib/upgrow/immutable_object.rb +57 -0
  9. data/lib/upgrow/immutable_struct.rb +40 -0
  10. data/lib/upgrow/input.rb +47 -0
  11. data/lib/upgrow/model.rb +35 -0
  12. data/lib/upgrow/repository.rb +12 -0
  13. data/lib/upgrow/result.rb +94 -0
  14. data/test/application_system_test_case.rb +13 -0
  15. data/test/dummy/app/actions/create_article_action.rb +13 -0
  16. data/test/dummy/app/actions/delete_article_action.rb +7 -0
  17. data/test/dummy/app/actions/edit_article_action.rb +10 -0
  18. data/test/dummy/app/actions/list_articles_action.rb +8 -0
  19. data/test/dummy/app/actions/show_article_action.rb +10 -0
  20. data/test/dummy/app/actions/update_article_action.rb +13 -0
  21. data/test/dummy/app/channels/application_cable/channel.rb +5 -0
  22. data/test/dummy/app/channels/application_cable/connection.rb +5 -0
  23. data/test/dummy/app/controllers/application_controller.rb +3 -0
  24. data/test/dummy/app/controllers/articles_controller.rb +64 -0
  25. data/test/dummy/app/helpers/application_helper.rb +102 -0
  26. data/test/dummy/app/inputs/article_input.rb +8 -0
  27. data/test/dummy/app/jobs/application_job.rb +9 -0
  28. data/test/dummy/app/mailers/application_mailer.rb +5 -0
  29. data/test/dummy/app/models/article.rb +6 -0
  30. data/test/dummy/app/records/application_record.rb +5 -0
  31. data/test/dummy/app/records/article_record.rb +5 -0
  32. data/test/dummy/app/repositories/article_repository.rb +4 -0
  33. data/test/dummy/config/application.rb +23 -0
  34. data/test/dummy/config/boot.rb +6 -0
  35. data/test/dummy/config/environment.rb +6 -0
  36. data/test/dummy/config/environments/development.rb +79 -0
  37. data/test/dummy/config/environments/production.rb +133 -0
  38. data/test/dummy/config/environments/test.rb +61 -0
  39. data/test/dummy/config/initializers/application_controller_renderer.rb +9 -0
  40. data/test/dummy/config/initializers/assets.rb +13 -0
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +12 -0
  42. data/test/dummy/config/initializers/content_security_policy.rb +31 -0
  43. data/test/dummy/config/initializers/cookies_serializer.rb +6 -0
  44. data/test/dummy/config/initializers/filter_parameter_logging.rb +7 -0
  45. data/test/dummy/config/initializers/inflections.rb +17 -0
  46. data/test/dummy/config/initializers/mime_types.rb +5 -0
  47. data/test/dummy/config/initializers/permissions_policy.rb +12 -0
  48. data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
  49. data/test/dummy/config/puma.rb +44 -0
  50. data/test/dummy/config/routes.rb +7 -0
  51. data/test/dummy/db/migrate/20210219211631_create_articles.rb +11 -0
  52. data/test/dummy/db/schema.rb +22 -0
  53. data/test/rails_helper.rb +21 -0
  54. data/test/system/articles_test.rb +109 -0
  55. data/test/test_helper.rb +3 -3
  56. data/test/upgrow/action_test.rb +25 -0
  57. data/test/upgrow/active_record_adapter_test.rb +94 -0
  58. data/test/upgrow/basic_repository_test.rb +73 -0
  59. data/test/upgrow/documentation_test.rb +12 -0
  60. data/test/upgrow/immutable_object_test.rb +60 -0
  61. data/test/upgrow/immutable_struct_test.rb +49 -0
  62. data/test/upgrow/input_test.rb +65 -0
  63. data/test/upgrow/model_test.rb +27 -0
  64. data/test/upgrow/result_test.rb +95 -0
  65. metadata +128 -7
  66. data/test/documentation_test.rb +0 -10
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'yard'
5
+
6
+ module Upgrow
7
+ class DocumentationTest < ActiveSupport::TestCase
8
+ test 'documentation is correctly written' do
9
+ assert_empty(%x(bundle exec yard --no-save --no-output --no-stats))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Upgrow
6
+ class ImmutableObjectTest < ActiveSupport::TestCase
7
+ class Sample < ImmutableObject
8
+ attribute :title
9
+ attribute :body
10
+ end
11
+
12
+ class SubSample < Sample
13
+ attribute :name
14
+ end
15
+
16
+ test '.attribute_names is empty by default' do
17
+ assert_empty ImmutableObject.attribute_names
18
+ end
19
+
20
+ test '.attribute_names returns a list of attribute names' do
21
+ assert_equal [:title, :body, :name], SubSample.attribute_names
22
+ end
23
+
24
+ test '.new creates a frozen instance with the given attributes' do
25
+ sample = Sample.new(title: 'volmer', body: 'hello')
26
+
27
+ assert_equal 'volmer', sample.title
28
+ assert_equal 'hello', sample.body
29
+ assert sample.frozen?
30
+ end
31
+
32
+ test 'it does not allow members to be mutated' do
33
+ sample = Sample.new(title: 'volmer', body: 'hello')
34
+
35
+ refute sample.respond_to?(:title=)
36
+ refute sample.respond_to?(:body=)
37
+ end
38
+
39
+ test '.new rejects attributes that do not exist' do
40
+ error = assert_raises(ArgumentError) do
41
+ Sample.new(title: 'volmer', body: 'hello', fake: 'error')
42
+ end
43
+
44
+ assert_equal 'Unknown attribute [:fake]', error.message
45
+ end
46
+
47
+ test '.new requires inherited attributes' do
48
+ sub_sample = SubSample.new(title: 'volmer', body: 'hello', name: 'rafael')
49
+ assert_equal 'volmer', sub_sample.title
50
+ assert_equal 'hello', sub_sample.body
51
+ assert_equal 'rafael', sub_sample.name
52
+ end
53
+
54
+ test '#attributes returns the collection of attributes' do
55
+ sample = Sample.new(title: 'volmer', body: 'hello')
56
+
57
+ assert_equal({ title: 'volmer', body: 'hello' }, sample.attributes)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Upgrow
6
+ class ImmutableStructTest < ActiveSupport::TestCase
7
+ test '.new creates a new Struct class with the given members as keyword arguments' do
8
+ struct_class = ImmutableStruct.new(:user, :post)
9
+
10
+ struct = struct_class.new(user: 'volmer', post: 'hello')
11
+
12
+ assert_equal([:user, :post], struct.members)
13
+ assert_equal(['volmer', 'hello'], struct.values)
14
+ assert struct.frozen?
15
+ end
16
+
17
+ test '.new accepts symbols only' do
18
+ error = assert_raises(ArgumentError) do
19
+ ImmutableStruct.new('Shopify', :user, :post)
20
+ end
21
+
22
+ assert_equal 'all members must be symbols', error.message
23
+ end
24
+
25
+ test 'it does not respond to []=' do
26
+ struct = ImmutableStruct.new(:user).new(user: 'volmer')
27
+ refute struct.respond_to?(:[]=)
28
+ end
29
+
30
+ test 'it does not allow members to be mutated' do
31
+ struct_class = ImmutableStruct.new(:user, :post)
32
+
33
+ struct = struct_class.new(user: 'volmer', post: 'hello')
34
+
35
+ refute struct.respond_to?(:user=)
36
+ refute struct.respond_to?(:post=)
37
+ end
38
+
39
+ test '.new requires all members' do
40
+ struct_class = ImmutableStruct.new(:user, :post)
41
+
42
+ error = assert_raises(KeyError) do
43
+ struct_class.new(user: 'volmer')
44
+ end
45
+
46
+ assert_equal 'key not found: :post', error.message
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'action_controller/metal/strong_parameters'
5
+
6
+ module Upgrow
7
+ class InputTest < ActiveSupport::TestCase
8
+ class SampleInput < Input
9
+ attribute :title
10
+ attribute :body
11
+
12
+ validates :title, presence: true
13
+ end
14
+
15
+ test '#errors is an empty Active Model Errors' do
16
+ input = Input.new
17
+ errors = input.errors
18
+ assert_empty errors
19
+ end
20
+
21
+ test '.new accepts individual arguments' do
22
+ input = SampleInput.new(title: 'volmer', body: 'hello')
23
+
24
+ assert_equal 'volmer', input.title
25
+ assert_equal 'hello', input.body
26
+ end
27
+
28
+ test '.new accepts a Hash of Symbols' do
29
+ args = { title: 'volmer', body: 'hello' }
30
+ input = SampleInput.new(args)
31
+
32
+ assert_equal 'volmer', input.title
33
+ assert_equal 'hello', input.body
34
+ end
35
+
36
+ test '.new accepts a Hash of Strings' do
37
+ args = { 'title' => 'volmer', 'body' => 'hello' }
38
+ input = SampleInput.new(args)
39
+
40
+ assert_equal 'volmer', input.title
41
+ assert_equal 'hello', input.body
42
+ end
43
+
44
+ test '.new accepts Action Controller parameters' do
45
+ args = ActionController::Parameters.new(
46
+ 'title' => 'volmer', 'body' => 'hello'
47
+ ).permit(:title, :body)
48
+
49
+ input = SampleInput.new(args)
50
+
51
+ assert_equal 'volmer', input.title
52
+ assert_equal 'hello', input.body
53
+ end
54
+
55
+ test '.valid? is true when validation passes' do
56
+ input = SampleInput.new(title: 'volmer')
57
+ assert_predicate input, :valid?
58
+ end
59
+
60
+ test '.valid? is false when validation fails' do
61
+ input = SampleInput.new
62
+ refute_predicate input, :valid?
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Upgrow
6
+ class ModelTest < ActiveSupport::TestCase
7
+ class SampleModel < Model
8
+ attribute :title
9
+ attribute :body
10
+ end
11
+
12
+ test '.attribute_names includes :id, :created_at, and :updated_at' do
13
+ expected = [:id, :created_at, :updated_at, :title, :body]
14
+ assert_equal expected, SampleModel.attribute_names
15
+ end
16
+
17
+ test '.new requires all attributes' do
18
+ error = assert_raises(KeyError) do
19
+ SampleModel.new(
20
+ title: 'volmer', id: 1, created_at: Time.now, updated_at: Time.now
21
+ )
22
+ end
23
+
24
+ assert_equal 'key not found: :body', error.message
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Upgrow
6
+ class ResultTest < ActiveSupport::TestCase
7
+ setup do
8
+ @errors = [:error]
9
+ end
10
+
11
+ test '.new returns a Result class with the given members and errors' do
12
+ result_class = Result.new(:user)
13
+ assert_equal([:user, :errors], result_class.members)
14
+ end
15
+
16
+ test '.new returns a Result class with only errors when called without arguments' do
17
+ result_class = Result.new
18
+ assert_equal([:errors], result_class.members)
19
+ end
20
+
21
+ test '.success returns a Result populated with the given values' do
22
+ result = Result.new(:user).success(user: 'volmer')
23
+ assert_equal 'volmer', result.user
24
+ assert_empty result.errors
25
+ end
26
+
27
+ test '.failure returns a Result populated with the given errors' do
28
+ result = Result.new(:user).failure(@errors)
29
+ assert_nil result.user
30
+ assert_equal @errors, result.errors
31
+ end
32
+
33
+ test '#and_then calls the given block and returns self for a successful Result' do
34
+ called = false
35
+
36
+ success = Result.new.success
37
+
38
+ returned_value = success.and_then { called = true }
39
+
40
+ assert called
41
+ assert_same success, returned_value
42
+ end
43
+
44
+ test '#or_else passes the Result values as an argument to the given block' do
45
+ success = Result.new(:user, :post)
46
+ .success(user: 'volmer', post: 'hello!')
47
+
48
+ success.and_then do |user:, post:|
49
+ assert_equal 'volmer', user
50
+ assert_equal 'hello!', post
51
+ end
52
+ end
53
+
54
+ test '#and_then does not call the given block and returns self for a failure Result' do
55
+ called = false
56
+
57
+ failure = Result.new.failure(@errors)
58
+
59
+ returned_value = failure.and_then { called = true }
60
+
61
+ refute called
62
+ assert_same failure, returned_value
63
+ end
64
+
65
+ test '#or_else does not call the given block and returns self for a successful Result' do
66
+ called = false
67
+
68
+ success = Result.new.success
69
+
70
+ returned_value = success.or_else { called = true }
71
+
72
+ refute called
73
+ assert_same success, returned_value
74
+ end
75
+
76
+ test '#or_else calls the given block and returns self for a failure Result' do
77
+ called = false
78
+
79
+ failure = Result.new.failure(@errors)
80
+
81
+ returned_value = failure.or_else { called = true }
82
+
83
+ assert called
84
+ assert_same failure, returned_value
85
+ end
86
+
87
+ test '#or_else passes the errors as an argument to the given block' do
88
+ failure = Result.new.failure(@errors)
89
+
90
+ failure.or_else do |errors|
91
+ assert_equal @errors, errors
92
+ end
93
+ end
94
+ end
95
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upgrow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-18 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6.1'
13
27
  description:
14
28
  email: gems@shopify.com
15
29
  executables: []
@@ -19,13 +33,71 @@ files:
19
33
  - README.md
20
34
  - Rakefile
21
35
  - lib/upgrow.rb
22
- - test/documentation_test.rb
36
+ - lib/upgrow/action.rb
37
+ - lib/upgrow/active_record_adapter.rb
38
+ - lib/upgrow/basic_repository.rb
39
+ - lib/upgrow/immutable_object.rb
40
+ - lib/upgrow/immutable_struct.rb
41
+ - lib/upgrow/input.rb
42
+ - lib/upgrow/model.rb
43
+ - lib/upgrow/repository.rb
44
+ - lib/upgrow/result.rb
45
+ - test/application_system_test_case.rb
46
+ - test/dummy/app/actions/create_article_action.rb
47
+ - test/dummy/app/actions/delete_article_action.rb
48
+ - test/dummy/app/actions/edit_article_action.rb
49
+ - test/dummy/app/actions/list_articles_action.rb
50
+ - test/dummy/app/actions/show_article_action.rb
51
+ - test/dummy/app/actions/update_article_action.rb
52
+ - test/dummy/app/channels/application_cable/channel.rb
53
+ - test/dummy/app/channels/application_cable/connection.rb
54
+ - test/dummy/app/controllers/application_controller.rb
55
+ - test/dummy/app/controllers/articles_controller.rb
56
+ - test/dummy/app/helpers/application_helper.rb
57
+ - test/dummy/app/inputs/article_input.rb
58
+ - test/dummy/app/jobs/application_job.rb
59
+ - test/dummy/app/mailers/application_mailer.rb
60
+ - test/dummy/app/models/article.rb
61
+ - test/dummy/app/records/application_record.rb
62
+ - test/dummy/app/records/article_record.rb
63
+ - test/dummy/app/repositories/article_repository.rb
64
+ - test/dummy/config/application.rb
65
+ - test/dummy/config/boot.rb
66
+ - test/dummy/config/environment.rb
67
+ - test/dummy/config/environments/development.rb
68
+ - test/dummy/config/environments/production.rb
69
+ - test/dummy/config/environments/test.rb
70
+ - test/dummy/config/initializers/application_controller_renderer.rb
71
+ - test/dummy/config/initializers/assets.rb
72
+ - test/dummy/config/initializers/backtrace_silencers.rb
73
+ - test/dummy/config/initializers/content_security_policy.rb
74
+ - test/dummy/config/initializers/cookies_serializer.rb
75
+ - test/dummy/config/initializers/filter_parameter_logging.rb
76
+ - test/dummy/config/initializers/inflections.rb
77
+ - test/dummy/config/initializers/mime_types.rb
78
+ - test/dummy/config/initializers/permissions_policy.rb
79
+ - test/dummy/config/initializers/wrap_parameters.rb
80
+ - test/dummy/config/puma.rb
81
+ - test/dummy/config/routes.rb
82
+ - test/dummy/db/migrate/20210219211631_create_articles.rb
83
+ - test/dummy/db/schema.rb
84
+ - test/rails_helper.rb
85
+ - test/system/articles_test.rb
23
86
  - test/test_helper.rb
87
+ - test/upgrow/action_test.rb
88
+ - test/upgrow/active_record_adapter_test.rb
89
+ - test/upgrow/basic_repository_test.rb
90
+ - test/upgrow/documentation_test.rb
91
+ - test/upgrow/immutable_object_test.rb
92
+ - test/upgrow/immutable_struct_test.rb
93
+ - test/upgrow/input_test.rb
94
+ - test/upgrow/model_test.rb
95
+ - test/upgrow/result_test.rb
24
96
  homepage: https://github.com/Shopify/upgrow
25
97
  licenses:
26
98
  - MIT
27
99
  metadata:
28
- source_code_uri: https://github.com/Shopify/upgrow/tree/v0.0.1
100
+ source_code_uri: https://github.com/Shopify/upgrow/tree/v0.0.2
29
101
  allowed_push_host: https://rubygems.org
30
102
  post_install_message:
31
103
  rdoc_options: []
@@ -45,7 +117,56 @@ requirements: []
45
117
  rubygems_version: 3.0.3
46
118
  signing_key:
47
119
  specification_version: 4
48
- summary: Patterns for Rails Architecture
120
+ summary: A sustainable architecture for Ruby on Rails.
49
121
  test_files:
122
+ - test/dummy/db/migrate/20210219211631_create_articles.rb
123
+ - test/dummy/db/schema.rb
124
+ - test/dummy/app/mailers/application_mailer.rb
125
+ - test/dummy/app/inputs/article_input.rb
126
+ - test/dummy/app/controllers/articles_controller.rb
127
+ - test/dummy/app/controllers/application_controller.rb
128
+ - test/dummy/app/jobs/application_job.rb
129
+ - test/dummy/app/records/application_record.rb
130
+ - test/dummy/app/records/article_record.rb
131
+ - test/dummy/app/helpers/application_helper.rb
132
+ - test/dummy/app/actions/create_article_action.rb
133
+ - test/dummy/app/actions/delete_article_action.rb
134
+ - test/dummy/app/actions/update_article_action.rb
135
+ - test/dummy/app/actions/list_articles_action.rb
136
+ - test/dummy/app/actions/edit_article_action.rb
137
+ - test/dummy/app/actions/show_article_action.rb
138
+ - test/dummy/app/models/article.rb
139
+ - test/dummy/app/channels/application_cable/channel.rb
140
+ - test/dummy/app/channels/application_cable/connection.rb
141
+ - test/dummy/app/repositories/article_repository.rb
142
+ - test/dummy/config/initializers/assets.rb
143
+ - test/dummy/config/initializers/filter_parameter_logging.rb
144
+ - test/dummy/config/initializers/content_security_policy.rb
145
+ - test/dummy/config/initializers/wrap_parameters.rb
146
+ - test/dummy/config/initializers/application_controller_renderer.rb
147
+ - test/dummy/config/initializers/permissions_policy.rb
148
+ - test/dummy/config/initializers/cookies_serializer.rb
149
+ - test/dummy/config/initializers/mime_types.rb
150
+ - test/dummy/config/initializers/backtrace_silencers.rb
151
+ - test/dummy/config/initializers/inflections.rb
152
+ - test/dummy/config/boot.rb
153
+ - test/dummy/config/routes.rb
154
+ - test/dummy/config/puma.rb
155
+ - test/dummy/config/application.rb
156
+ - test/dummy/config/environments/development.rb
157
+ - test/dummy/config/environments/test.rb
158
+ - test/dummy/config/environments/production.rb
159
+ - test/dummy/config/environment.rb
160
+ - test/rails_helper.rb
161
+ - test/application_system_test_case.rb
162
+ - test/system/articles_test.rb
163
+ - test/upgrow/immutable_object_test.rb
164
+ - test/upgrow/immutable_struct_test.rb
165
+ - test/upgrow/result_test.rb
166
+ - test/upgrow/basic_repository_test.rb
167
+ - test/upgrow/action_test.rb
168
+ - test/upgrow/documentation_test.rb
169
+ - test/upgrow/model_test.rb
170
+ - test/upgrow/input_test.rb
171
+ - test/upgrow/active_record_adapter_test.rb
50
172
  - test/test_helper.rb
51
- - test/documentation_test.rb