obvious 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bf4de686eee48c524a3037620e21a154db8c75fce3ff8db780afc25dc376202
4
- data.tar.gz: c4930e55f1420a9b40996fc042052f267548b3f6017055ad69355c44bad28f7e
3
+ metadata.gz: 9a0c1346518213e685185d08916b2c573697ca5d6be5763f8cfe245febeac4f0
4
+ data.tar.gz: 2125df9f05284d2e34b16edb85ee14f73d1d1f2a296df90c7a2b4e2a795ab81f
5
5
  SHA512:
6
- metadata.gz: 377a83eba55eeadeb63bdadd1a12f72a81507b5d029486add3ffba65fd81c4de929936e435bc73ac0816185bab6dff2a0aa1b4ecfcf527fa36d4dbdc13abaf81
7
- data.tar.gz: 6f7a51c4037baa95be253c62a801f1c8204e662b089bc45bd7f6db1df94f6c39d1130625fb745a7c558111662c5baeaf59372817a077f17d14faf7af2ce0b394
6
+ metadata.gz: 1f8684fe2bc370eb3d2cec4933e3281a00b0633a5829cdee580b36632d330e6b71ba605612bd1ef5f5cfa6884ed66369a50117f68d3b1a9a9ec73a0c3e5bdfda
7
+ data.tar.gz: f393f71805593ff5b748477ebe9486148c356fdb73b1fb09f108453611ceabf4cce982768914c10de719012b0782659bf57ab4e91357871173551d60fb4503ff
@@ -16,4 +16,4 @@ jobs:
16
16
  ruby-version: ${{ matrix.ruby }}
17
17
  bundler-cache: true
18
18
  - run: |
19
- bundle exec rspec
19
+ ruby -Ilib:test test/*_test.rb
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.2.0]
6
+
7
+ ### Added
8
+
9
+ ### Changed
10
+
11
+ - Updated README to be current
12
+ - Removed generators from Obvious
13
+ - Refactored Obvious::Obj#define to be simpler
14
+ - Replaced RSPec with Minitest for testing
15
+
16
+ ### Fixed
17
+
18
+ - Fixed namespace issues with Contract errors
19
+ - Updated project URL on Rubygems listing
data/Gemfile.lock CHANGED
@@ -1,25 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- obvious (0.1.0)
4
+ obvious (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- diff-lcs (1.5.0)
10
- rspec (3.10.0)
11
- rspec-core (~> 3.10.0)
12
- rspec-expectations (~> 3.10.0)
13
- rspec-mocks (~> 3.10.0)
14
- rspec-core (3.10.1)
15
- rspec-support (~> 3.10.0)
16
- rspec-expectations (3.10.1)
17
- diff-lcs (>= 1.2.0, < 2.0)
18
- rspec-support (~> 3.10.0)
19
- rspec-mocks (3.10.2)
20
- diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.10.0)
22
- rspec-support (3.10.3)
23
9
 
24
10
  PLATFORMS
25
11
  ruby
@@ -28,7 +14,6 @@ PLATFORMS
28
14
 
29
15
  DEPENDENCIES
30
16
  obvious!
31
- rspec
32
17
 
33
18
  BUNDLED WITH
34
19
  2.3.4
data/README.md CHANGED
@@ -1,20 +1,9 @@
1
1
  # Obvious
2
2
 
3
- Obvious is an architecture framework. The goal is to provide architectural structure for a highly testable system that is
4
- obvious to understand and where both the front end UI and back end infrastructure are treated as implementation details
5
- independent of the app logic itself.
6
-
7
- You can get a full explanation of Obvious at http://obvious.retromocha.com
8
-
9
-
10
- # Notice:
11
-
12
- This project is no longer under active development is only made available for historical purposes.
13
-
14
- Right now [Brian is working on a little of this](http://brianknapp.me/now/) and [Shawn is working on a little of that](http://shawnbaden.com/now/).
15
-
16
- Most of our spare energy goes to the [Unbranded Pocket Notebook](https://www.amazon.com/dp/B00ZGE1914/) and the [Unbranded Pocket Journal](https://www.amazon.com/dp/B016LB2XYW).
17
-
3
+ Obvious is an architecture framework. The goal is to provide architectural
4
+ structure for a highly testable system that is obvious to understand and where
5
+ both the front end UI and back end infrastructure are treated as implementation
6
+ details independent of the app logic itself.
18
7
 
19
8
  ## Installation
20
9
 
@@ -25,23 +14,3 @@ Add this line to your application's Gemfile:
25
14
  And then execute:
26
15
 
27
16
  $ bundle
28
-
29
- Or install it yourself as:
30
-
31
- $ gem install obvious
32
-
33
- ## Usage
34
-
35
- Obvious is designed to be used in two ways - as a gem you require in your Obvious projects and also as an Obvious project
36
- generation tool.
37
-
38
- The project generation tool is run by executing...
39
-
40
- $ obvious generate
41
-
42
- in a directory containing a decriptors directory. You can read more about descriptors on the Obvious page or see an example
43
- in the Obvious Status example app: https://github.com/RetroMocha/obvious_status.
44
-
45
- Currently the footprint of the Obvious library is quite small. The most important things defined so far are the Contract class
46
- and the Hash.has_shape? method. The rest of what makes an Obvious app interesting is the structure itself, not the libraries Obvious
47
- provides.
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+ task :default => :test
@@ -94,8 +94,8 @@ module Obvious
94
94
  def call_method method, input, input_shape, output_shape
95
95
  if input != nil && input_shape != nil
96
96
  has_shape, error_field = input.has_shape? input_shape, true
97
- unless has_shape
98
- raise ContractInputError, "incorrect input data format field #{error_field}"
97
+ unless has_shape
98
+ raise Obvious::ContractInputError, "incorrect input data format field #{error_field}"
99
99
  end
100
100
 
101
101
  result = self.send method, input
@@ -106,11 +106,11 @@ module Obvious
106
106
  # check output
107
107
  # output should never be nil
108
108
  if result == nil
109
- raise ContractOutputError, 'incorrect output data format'
109
+ raise Obvious::ContractOutputError, 'incorrect output data format'
110
110
  end
111
111
 
112
112
  if result === {}
113
- raise DataNotFoundError, 'data was not found'
113
+ raise Obvious::DataNotFoundError, 'data was not found'
114
114
  end
115
115
 
116
116
  # we are looking for result to be a True object
@@ -118,7 +118,7 @@ module Obvious
118
118
  if output_shape == result
119
119
  return result
120
120
  else
121
- raise ContractOutputError, 'incorrect output data format'
121
+ raise Obvious::ContractOutputError, 'incorrect output data format'
122
122
  end
123
123
  end
124
124
 
@@ -128,20 +128,20 @@ module Obvious
128
128
  inner_shape = output_shape[0]
129
129
  result.each do |item|
130
130
  has_shape, error_field = item.has_shape? inner_shape, true
131
- unless has_shape
132
- raise ContractOutputError, "incorrect output data format field #{error_field}"
131
+ unless has_shape
132
+ raise Obvious::ContractOutputError, "incorrect output data format field #{error_field}"
133
133
  end
134
134
  end
135
135
 
136
136
  return result
137
137
  end
138
- raise ContractOutputError, 'incorrect output data format'
138
+ raise Obvious::ContractOutputError, 'incorrect output data format'
139
139
  end
140
140
 
141
141
  # we want result to be true or false
142
142
  if output_shape == :true_false
143
143
  unless result == true || result == false
144
- raise ContractOutputError, 'incorrect output data format'
144
+ raise Obvious::ContractOutputError, 'incorrect output data format'
145
145
  end
146
146
 
147
147
  return result
@@ -149,8 +149,8 @@ module Obvious
149
149
 
150
150
  # we want result to be output_shape's shape
151
151
  has_shape, error_field = result.has_shape? output_shape, true
152
- unless has_shape
153
- raise ContractOutputError, "incorrect output data format field #{error_field}"
152
+ unless has_shape
153
+ raise Obvious::ContractOutputError, "incorrect output data format field #{error_field}"
154
154
  end
155
155
 
156
156
  result
@@ -158,6 +158,15 @@ module Obvious
158
158
 
159
159
  end
160
160
 
161
+
162
+ class ContractInputError < StandardError
163
+ end
164
+
165
+ class ContractOutputError < StandardError
166
+ end
167
+
168
+ class DataNotFoundError < StandardError
169
+ end
161
170
  end
162
171
 
163
172
  # via https://github.com/citizen428/shenanigans/blob/master/lib/shenanigans/hash/has_shape_pred.rb
@@ -178,28 +187,28 @@ class Hash
178
187
  if return_field
179
188
  return r, f
180
189
  else
181
- return r
190
+ return r
182
191
  end
183
192
  }
184
-
193
+
185
194
  # I added an empty check
186
195
  if self.empty?
187
196
  return return_value.call shape.empty?, nil
188
- end
189
-
197
+ end
198
+
190
199
  self.each do |k, v|
191
200
  return return_value.call false, k if shape[k] == nil
192
- end
201
+ end
193
202
 
194
203
  shape.each do |k, v|
195
204
  # hash_value
196
205
  hv = self[k]
197
- return return_value.call false, k unless self.has_key? k
206
+ return return_value.call false, k unless self.has_key? k
198
207
 
199
208
  next if hv === nil
200
209
 
201
- if Hash === hv
202
- return hv.has_shape?(v, return_field)
210
+ if Hash === hv
211
+ return hv.has_shape?(v, return_field)
203
212
  else
204
213
  return return_value.call false, k unless v === hv
205
214
  end
@@ -211,18 +220,8 @@ class Hash
211
220
  def nil_fields? list
212
221
  list.each do |field|
213
222
  return true, field unless self[field]
214
- end
215
-
223
+ end
224
+
216
225
  return false, nil
217
226
  end
218
227
  end
219
-
220
- class ContractInputError < StandardError
221
- end
222
-
223
- class ContractOutputError < StandardError
224
- end
225
-
226
- class DataNotFoundError < StandardError
227
- end
228
-
data/lib/obvious/obj.rb CHANGED
@@ -5,31 +5,29 @@ module Obvious
5
5
  base.extend ClassMethods
6
6
  end
7
7
  end
8
-
8
+
9
9
  module ClassMethods
10
10
 
11
- def define method, input = {}, &block
12
- define_method(method) do |method_input = {}|
11
+ def define method, input = {}, &block
12
+ define_method(method) do |method_input = {}|
13
13
  block_input = {}
14
- method_input.each do |k,v|
15
- if input[k].nil?
14
+ method_input.each do |k,v|
15
+ if input[k].nil?
16
16
  raise ArgumentError.new "invalid input field #{k}"
17
- end
18
-
19
- unless v.is_a? input[k][1]
20
- raise ArgumentError.new "invalid type for #{k} expected #{input[k][1]}"
21
- end
17
+ end
22
18
 
23
- block_input[input[k][0]] = v
19
+ unless v.is_a? input[k]
20
+ raise ArgumentError.new "invalid type for #{k} expected #{input[k]}"
21
+ end
24
22
  end
25
-
23
+
26
24
  input.each do |k,v|
27
- if block_input[v[0]].nil?
25
+ if method_input[k].nil?
28
26
  raise ArgumentError.new "missing input field #{k}"
29
27
  end
30
28
  end
31
29
 
32
- self.instance_exec block_input, &block
30
+ self.instance_exec method_input, &block
33
31
  end
34
32
  end
35
33
 
@@ -1,3 +1,3 @@
1
1
  module Obvious
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/obvious.rb CHANGED
@@ -2,4 +2,3 @@ require 'obvious/version'
2
2
  require 'obvious/contract'
3
3
  require 'obvious/entity'
4
4
  require 'obvious/obj'
5
- require_relative 'generators/application_generator'
data/obvious.gemspec CHANGED
@@ -6,16 +6,14 @@ require 'obvious/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "obvious"
8
8
  gem.version = Obvious::VERSION
9
- gem.authors = ["Brian Knapp"]
10
- gem.email = ["brianknapp@gmail.com"]
9
+ gem.authors = ["Brian Knapp", "Shawn Baden"]
10
+ gem.email = ["brianknapp@gmail.com", "shawnbaden@hotmail.com"]
11
11
  gem.description = "A set of tools to build apps using the Obvious Architecture"
12
12
  gem.summary = "Clean Architecture framework"
13
- gem.homepage = "http://obvious.retromocha.com/"
14
-
13
+ gem.homepage = "https://github.com/RetroMocha/obvious"
14
+ gem.license = "MIT"
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
-
20
- gem.add_development_dependency "rspec"
21
19
  end
@@ -0,0 +1,62 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/obvious/contract'
3
+
4
+ class TestContract < Obvious::Contract
5
+ contract_for :test, {
6
+ input: { id: Integer },
7
+ output: { id: Integer, value: String }
8
+ }
9
+
10
+ def test input
11
+ { id: 1, value: 'this is a test' }
12
+ end
13
+ end
14
+
15
+ class ContractTest < Minitest::Test
16
+ def test_valid_input
17
+ result = TestContract.new.test(id: 1)
18
+ assert_equal({id: 1, value: 'this is a test'}, result)
19
+ end
20
+
21
+ def test_invalid_input
22
+ assert_raises Obvious::ContractInputError do
23
+ TestContract.new.test(Hash.new)
24
+ end
25
+ end
26
+
27
+ def test_empty_hash_return
28
+ assert_raises Obvious::DataNotFoundError do
29
+ tc = TestContract.new
30
+ tc.stub :test_alias, {} do
31
+ tc.test(id: 1)
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_nil_return
37
+ assert_raises Obvious::ContractOutputError do
38
+ tc = TestContract.new
39
+ tc.stub :test_alias, nil do
40
+ tc.test(id: 1)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ class HashTest < Minitest::Test
47
+ def test_valid_has_shape
48
+ assert({id: 1}.has_shape?(id: Integer))
49
+ end
50
+
51
+ def test_invalid_has_shape
52
+ refute({id: 1}.has_shape?(id: String))
53
+ end
54
+
55
+ def test_has_shape_allow_nil_values
56
+ assert({id: nil}.has_shape?({id: String}))
57
+ end
58
+
59
+ def test_has_shape_return_invalid_field
60
+ assert_equal([false, :id], { id: 1 }.has_shape?({id: String}, true))
61
+ end
62
+ end
@@ -0,0 +1,76 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/obvious/entity'
3
+
4
+ class Thing < Obvious::Entity
5
+ value :id, Integer
6
+ value :name, String
7
+ end
8
+
9
+ class Thing2 < Obvious::Entity
10
+ value :foo , String
11
+
12
+ validation :something, -> {
13
+ if foo != "hello world"
14
+ msg = "Validation Error: Invalid value for foo, should be 'hello world'"
15
+ raise Obvious::ValidationError.new msg
16
+ end
17
+ }
18
+
19
+ def modify_foo
20
+ @values[:foo] = 100
21
+ end
22
+ end
23
+
24
+ class Thing3 < Obvious::Entity
25
+ value :foo , String
26
+
27
+ validation :something, -> {
28
+ @values[:foo] = 12
29
+ }
30
+ end
31
+
32
+
33
+ # Test code begins here
34
+
35
+ class EntityTest < Minitest::Test
36
+ def test_valid_input
37
+ t = Thing.new(name: 'Thing', id: 1)
38
+ assert_equal('Thing', t.name)
39
+ assert_equal(1, t.id)
40
+ end
41
+
42
+ def test_invalid_input_types
43
+ assert_raises Obvious::TypeError do
44
+ Thing.new(name: nil, id: nil)
45
+ end
46
+ end
47
+
48
+ def test_invalid_extra_field
49
+ assert_raises Obvious::ShapeError do
50
+ Thing.new(name: 'Thing', id: 1, extra: 'should explode')
51
+ end
52
+ end
53
+
54
+ def test_method_modify_value
55
+ assert_raises RuntimeError do
56
+ Thing2.new(foo: 'hello world').modify_foo
57
+ end
58
+ end
59
+
60
+ def test_to_hash
61
+ t = Thing.new(name: 'Thing', id: 1)
62
+ assert_equal({name: 'Thing', id: 1}, t.to_hash)
63
+ end
64
+
65
+ def test_failed_validation
66
+ assert_raises Obvious::ValidationError do
67
+ Thing2.new(foo: 'not valid I promise!')
68
+ end
69
+ end
70
+
71
+ def test_modify_value_inside_validation
72
+ assert_raises RuntimeError do
73
+ Thing3.new(foo: 'hello world')
74
+ end
75
+ end
76
+ end
data/test/obj_test.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/obvious/obj'
3
+
4
+ class TestObj
5
+ include Obvious::Obj
6
+
7
+ def initialize
8
+ @local = 'set!'
9
+ end
10
+
11
+ define :defined_method, foo: String, bar: Integer do |input|
12
+ input
13
+ end
14
+
15
+ define :defined_local do |input|
16
+ @local
17
+ end
18
+
19
+ define :early_return_example do |input|
20
+ next true
21
+ false
22
+ end
23
+ end
24
+
25
+ class ObjTest < Minitest::Test
26
+ def test_valid_input
27
+ result = TestObj.new.defined_method foo: 'hello', bar: 12
28
+ assert_equal({foo: 'hello', bar: 12}, result)
29
+ end
30
+
31
+ def test_access_instance_variables
32
+ result = TestObj.new.defined_local
33
+ assert_equal('set!', result)
34
+ end
35
+
36
+ def test_missing_parameters
37
+ error = assert_raises ArgumentError do
38
+ TestObj.new.defined_method foo: 'hello'
39
+ end
40
+ assert_equal('missing input field bar', error.message)
41
+ end
42
+
43
+ def test_extra_parameters
44
+ error = assert_raises ArgumentError do
45
+ TestObj.new.defined_method foo: 'hello', bar: 12, extra: 'fail'
46
+ end
47
+ assert_equal('invalid input field extra', error.message)
48
+ end
49
+
50
+ def test_invalid_types
51
+ error = assert_raises ArgumentError do
52
+ TestObj.new.defined_method foo: 1, bar: 12
53
+ end
54
+ assert_equal('invalid type for foo expected String', error.message)
55
+
56
+ error = assert_raises ArgumentError do
57
+ TestObj.new.defined_method foo: 'hello', bar: nil
58
+ end
59
+ assert_equal('invalid type for bar expected Integer', error.message)
60
+ end
61
+
62
+ def test_early_return
63
+ assert(TestObj.new.early_return_example)
64
+ end
65
+ end
metadata CHANGED
@@ -1,67 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obvious
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Knapp
8
+ - Shawn Baden
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2022-01-26 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rspec
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
12
+ date: 2022-02-02 00:00:00.000000000 Z
13
+ dependencies: []
27
14
  description: A set of tools to build apps using the Obvious Architecture
28
15
  email:
29
16
  - brianknapp@gmail.com
30
- executables:
31
- - obvious
17
+ - shawnbaden@hotmail.com
18
+ executables: []
32
19
  extensions: []
33
20
  extra_rdoc_files: []
34
21
  files:
35
22
  - ".github/workflows/obvious.yml"
36
23
  - ".gitignore"
24
+ - CHANGELOG.md
37
25
  - Gemfile
38
26
  - Gemfile.lock
39
27
  - LICENSE.txt
40
28
  - README.md
41
29
  - Rakefile
42
- - bin/obvious
43
- - lib/generators/application_generator.rb
44
- - lib/generators/descriptor.rb
45
- - lib/generators/helpers/application.rb
46
30
  - lib/obvious.rb
47
31
  - lib/obvious/contract.rb
48
32
  - lib/obvious/entity.rb
49
- - lib/obvious/files/Rakefile
50
- - lib/obvious/files/external/fs_plug.rb
51
- - lib/obvious/files/external/mongo_plug.rb
52
- - lib/obvious/files/external/mysql_plug.rb
53
- - lib/obvious/files/external/s3_plug.rb
54
33
  - lib/obvious/obj.rb
55
34
  - lib/obvious/version.rb
56
35
  - obvious.gemspec
57
- - spec/.spec_helper.rb.swp
58
- - spec/contract_spec.rb
59
- - spec/entity_spec.rb
60
- - spec/generators/descriptor_spec.rb
61
- - spec/obj_spec.rb
62
- - spec/spec_helper.rb
63
- homepage: http://obvious.retromocha.com/
64
- licenses: []
36
+ - test/contract_test.rb
37
+ - test/entity_test.rb
38
+ - test/obj_test.rb
39
+ homepage: https://github.com/RetroMocha/obvious
40
+ licenses:
41
+ - MIT
65
42
  metadata: {}
66
43
  post_install_message:
67
44
  rdoc_options: []
@@ -83,9 +60,6 @@ signing_key:
83
60
  specification_version: 4
84
61
  summary: Clean Architecture framework
85
62
  test_files:
86
- - spec/.spec_helper.rb.swp
87
- - spec/contract_spec.rb
88
- - spec/entity_spec.rb
89
- - spec/generators/descriptor_spec.rb
90
- - spec/obj_spec.rb
91
- - spec/spec_helper.rb
63
+ - test/contract_test.rb
64
+ - test/entity_test.rb
65
+ - test/obj_test.rb
data/bin/obvious DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'obvious'
4
-
5
- if ARGV[0] == 'generate'
6
- Obvious::Generators::ApplicationGenerator.generate
7
- end