upgrow 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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