definition 0.1.0.rc1 → 0.1.0.rc2

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: 5d4178b9d52b38f362ceeefc4e4b593c08bc1db136f39f43791c146890eebeec
4
- data.tar.gz: 35a2df7826b4d9e77fa425711fcbff1ba1024438b355240a5aa5ee79a535e2d5
3
+ metadata.gz: 3af4089033df18151f417df6667ab1f76b266d35728297abc1ead799bb25dab9
4
+ data.tar.gz: 82e3b50fc7e7bdafd0317669c6960924627808f6ae19086a383ab91b3d3ead8e
5
5
  SHA512:
6
- metadata.gz: 1f249e44ce43c29716f6943a8373399797d928f1796d42f6ead9f13261595e297cf4dc37418ef99d53717f6c57a5988ae78c01bab3c5cd91e227b3e150b7efae
7
- data.tar.gz: 413f8ccf960d01faad85221108feda1b3c7ac41a0766c76d36872e58484f65d2c043a1f71d6fdde2de05814908b1325caeb0e2953f46281f625fe26eefc7f3db
6
+ metadata.gz: ee6a8ef92b6844cbe89b9e18bccb10b12b4068f7726d73c1d24296873b61cf60dc2478da1948a8350017c7be868c466dce4a6a2482e2672a0959567f8fd8e7e5
7
+ data.tar.gz: f8ed3f1933198bf18f750334fdd1662666c795dc2dbb80fbf84680c62dce436670ff8e4904bc32c77926e6ee0de0dc189eef304eac1a94f1c802c486b061f836
@@ -75,3 +75,6 @@ RSpec/MultipleExpectations:
75
75
 
76
76
  RSpec/MessageExpectation:
77
77
  Enabled: false
78
+
79
+ RSpec/RepeatedExample:
80
+ Enabled: false
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/Goltergaul/definition.svg?branch=master)][travis]
4
4
  [![Gem Version](https://badge.fury.io/rb/definition.svg)][rubygems]
5
5
 
6
- Simple and composable validation and coercion of data structures
6
+ Simple and composable validation and coercion of data structures. It also includes a ValueObject for convinience.
7
7
 
8
8
  ## Installation
9
9
 
@@ -63,6 +63,44 @@ conform_result.value # => {title: "My first blog post", body: "Shortest one ever
63
63
  Because definitions do not only validate input but also transform input, we use
64
64
  the term `conform` which stands for validation and coercion.
65
65
 
66
+ ### Value Objects
67
+
68
+ ```ruby
69
+ class User < Definition::ValueObject
70
+ definition(Definition.Keys do
71
+ required :username, Definition.Type(String)
72
+ required :password, Definition.Type(String)
73
+ end)
74
+ end
75
+
76
+ user = User.new(username: "johndoe", password: "zg(2ds8x2/")
77
+ user.username # => "johndoe"
78
+ user[:username] # => "johndoe"
79
+ user.username = "Alice" # => NoMethodError (ValueObjects are immutable)
80
+ user[:username] = "Alice" # => FrozenError (ValueObjects are immutable)
81
+
82
+ User.new(username: "johndoe") # => Definition::InvalidValueObjectError: hash does not include :last_name
83
+ ```
84
+
85
+ Value objects delegate all calls to the output value of the defined definition,
86
+ so in this example you can use all methods that are defined on `Hash` also on the
87
+ user object. If you use a `Keys` definition, the value object additionally defines
88
+ convenient accessor methods for all attributes.
89
+
90
+ Value Objects can also be used for all other data structures that can be validated
91
+ by a definition, for example arrays:
92
+
93
+ ```ruby
94
+ class IntegerArray < Definition::ValueObject
95
+ definition(Definition.Each(Definition.Type(Integer)))
96
+ end
97
+
98
+ array = IntegerArray.new([1,2,3])
99
+ array.first # => 1
100
+
101
+ IntegerArray.new([1,2,"3"]) # => Definition::InvalidValueObjectError: Not all items conform with each: { Item "3" did not conform to each: { Is of type String instead of Integer } }
102
+ ```
103
+
66
104
  ### Conforming Hashes
67
105
 
68
106
  Hashes can be conformed by using the `Keys` definition. It allows you to configure
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "definition/version"
4
4
  require "definition/dsl"
5
+ require "definition/value_object"
5
6
 
6
7
  module Definition
7
8
  extend Dsl
@@ -31,6 +31,10 @@ module Definition
31
31
  Conformer.new(self, value).conform
32
32
  end
33
33
 
34
+ def keys
35
+ required_definitions.keys + optional_definitions.keys
36
+ end
37
+
34
38
  class Conformer
35
39
  def initialize(definition, value)
36
40
  self.definition = definition
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Definition
4
+ class InvalidValueObjectError < StandardError; end
5
+ class NotConfiguredError < StandardError; end
6
+
7
+ class ValueObject < SimpleDelegator
8
+ def initialize(args = nil, **kwargs)
9
+ result = self.class.conform(args || kwargs)
10
+ raise InvalidValueObjectError.new(result.error_message) unless result.passed?
11
+
12
+ super(result.value.freeze)
13
+ end
14
+
15
+ class << self
16
+ def conform(value)
17
+ unless @definition
18
+ raise Definition::NotConfiguredError.new(
19
+ "Value object has not been configured with a defintion. Use .definition to set a definition"
20
+ )
21
+ end
22
+
23
+ @definition.conform(value)
24
+ end
25
+
26
+ def definition(definition)
27
+ @definition = definition
28
+ define_accessor_methods if definition.is_a?(Definition::Types::Keys)
29
+ end
30
+
31
+ def define_accessor_methods
32
+ @definition.keys.each do |key|
33
+ define_method(key) { self[key] }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Definition
4
- VERSION = "0.1.0.rc1"
4
+ VERSION = "0.1.0.rc2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: definition
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.rc1
4
+ version: 0.1.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Goltermann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-30 00:00:00.000000000 Z
11
+ date: 2019-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: approvals
@@ -252,6 +252,7 @@ files:
252
252
  - lib/definition/types/lambda.rb
253
253
  - lib/definition/types/or.rb
254
254
  - lib/definition/types/type.rb
255
+ - lib/definition/value_object.rb
255
256
  - lib/definition/version.rb
256
257
  homepage: https://github.com/Goltergaul/definition
257
258
  licenses: