evil-struct 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1f83443166df4c93a0697048a1bb7a6c0757ff9b
4
+ data.tar.gz: a6942c1bda0626e51fdd0163cfe23d3e0098767c
5
+ SHA512:
6
+ metadata.gz: a887a24df325459ea5bdd6b0ce655a7c07d038a65272268ce281e3b62d1304689dc134d57c5cc704cee84dce6a122d359781090c3c0ef5b8ba98227549c2c7e5
7
+ data.tar.gz: 8dfc7556f97bb308624d9755074b16273fda5bea610e4f599b0e0a98c6305c721638a32b785659ed1d4085d6a2109a3e46619955af27e09fcdd219a8121526e9
data/.codeclimate.yml ADDED
@@ -0,0 +1,18 @@
1
+ ---
2
+ engines:
3
+ bundler-audit:
4
+ enabled: true
5
+ duplication:
6
+ enabled: true
7
+ config:
8
+ languages:
9
+ - ruby
10
+ fixme:
11
+ enabled: true
12
+ rubocop:
13
+ enabled: true
14
+ ratings:
15
+ paths:
16
+ - "**.rb"
17
+ exclude_paths:
18
+ - spec/
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,38 @@
1
+ ---
2
+ AllCops:
3
+ DisplayCopNames: true
4
+ DisplayStyleGuide: true
5
+ StyleGuideCopsOnly: true
6
+ TargetRubyVersion: 2.3
7
+
8
+ Style/Alias:
9
+ Enabled: false
10
+
11
+ Style/ClassAndModuleChildren:
12
+ EnforcedStyle: compact
13
+
14
+ Style/FileName:
15
+ Enabled: false
16
+
17
+ Style/FrozenStringLiteralComment:
18
+ Enabled: false
19
+
20
+ Style/StringLiterals:
21
+ EnforcedStyle: double_quotes
22
+
23
+ Style/StringLiteralsInInterpolation:
24
+ EnforcedStyle: double_quotes
25
+
26
+ # Settings for Struct#hashify
27
+
28
+ Metrics/CyclomaticComplexity:
29
+ Max: 7
30
+
31
+ Metrics/AbcSize:
32
+ Max: 17.12
33
+
34
+ Metrics/MethodLength:
35
+ Max: 15
36
+
37
+ Metrics/PerceivedComplexity:
38
+ Max: 8
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ script:
6
+ - bundle exec rspec
7
+ - bundle exec rubocop
8
+ rvm:
9
+ - '2.3.0'
10
+ - ruby-head
11
+ - jruby-9.1.0.0
12
+ - jruby-head
13
+ before_install: gem install bundler -v 1.12.5
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: ruby-head
17
+ - rvm: jruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in evil-struct.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Andrew Kozin (aka nepalez)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Evil::Struct
2
+
3
+ Nested structure with type constraints, based on the [dry-initializer][dry-initializer] DSL.
4
+
5
+ <a href="https://evilmartians.com/">
6
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
7
+
8
+ [![Gem Version][gem-badger]][gem]
9
+ [![Build Status][travis-badger]][travis]
10
+ [![Dependency Status][gemnasium-badger]][gemnasium]
11
+ [![Inline docs][inch-badger]][inch]
12
+
13
+ [gem-badger]: https://img.shields.io/gem/v/evil-struct.svg?style=flat
14
+ [gem]: https://rubygems.org/gems/evil-struct
15
+ [gemnasium-badger]: https://img.shields.io/gemnasium/nepalez/evil-struct.svg?style=flat
16
+ [gemnasium]: https://gemnasium.com/nepalez/evil-struct
17
+ [inch-badger]: http://inch-ci.org/github/nepalez/evil-struct.svg
18
+ [inch]: https://inch-ci.org/github/nepalez/evil-struct
19
+ [travis-badger]: https://img.shields.io/travis/nepalez/evil-struct/master.svg?style=flat
20
+ [travis]: https://travis-ci.org/nepalez/evil-struct
21
+
22
+ ## Installation
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ ```ruby
27
+ gem 'evil-struct'
28
+ ```
29
+
30
+ And then execute:
31
+
32
+ $ bundle
33
+
34
+ Or install it yourself as:
35
+
36
+ $ gem install evil-struct
37
+
38
+ ## Synopsis
39
+
40
+ The structure is like [dry-struct][dry-struct] except for it controls optional attributes and default values aside of type constraints.
41
+
42
+ Its DSL is taken from [dry-initializer][dry-initializer]. Its method `attribute` is just an alias for `option`.
43
+
44
+ ```ruby
45
+ require "evil-struct"
46
+ require "dry-types"
47
+
48
+ class Product < Evil::Struct
49
+ attribute :title
50
+ attribute :price, Dry::Types["coercible.float"]
51
+ attribute :quantity, Dry::Types["coercible.int"], default: proc { 0 }
52
+
53
+ # shared options
54
+ attributes optional: true do
55
+ attribute :subtitle
56
+ attribute :description
57
+ end
58
+ end
59
+
60
+ # Accepts both symbolic and string keys.
61
+ # Class methods `[]`, `call`, and `load` are just aliases for `new`
62
+ product = Product[title: "apple", "price" => "10.9", description: "a fruit"]
63
+
64
+ # Attributes are available via methods or `[]`
65
+ product.title # => "apple"
66
+ product[:price] # => 10.9
67
+ product["quantity"] # => 0
68
+ product.description # => "a fruit"
69
+
70
+ # unassigned value differs from `nil`
71
+ product.subtitle # => Dry::Initializer::UNDEFINED
72
+
73
+ # Raises in case a mandatory value not assigned
74
+ Product.new # BOOM! because neither title, nor price are assigned
75
+
76
+ # Hashifies all attributes except for undefined subtitle
77
+ # You can use `dump` as an alias for `to_h`
78
+ product.to_h
79
+ # => { title: "apple", price: 10.9, description: "a fruit", quantity: 0 }
80
+
81
+ # The structure is comparable to any object that responds to `#to_h`
82
+ product == { title: "apple", price: 10.9, description: "a fruit", quantity: 0 }
83
+ # => true
84
+ ```
85
+
86
+ ## Compatibility
87
+
88
+ Tested under rubies [compatible to MRI 2.2+](.travis.yml).
89
+
90
+ ## Contributing
91
+
92
+ * [Fork the project](https://github.com/dry-rb/dry-initializer)
93
+ * Create your feature branch (`git checkout -b my-new-feature`)
94
+ * Add tests for it
95
+ * Commit your changes (`git commit -am '[UPDATE] Add some feature'`)
96
+ * Push to the branch (`git push origin my-new-feature`)
97
+ * Create a new Pull Request
98
+
99
+ ## License
100
+
101
+ The gem is available as open source under the terms of the [MIT License][license].
102
+
103
+ [dry-initializer]: https://rom-rb.org/gems/dry-initializer
104
+ [dry-struct]: https://rom-rb.org/gems/dry-struct
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/codeclimate.yml ADDED
@@ -0,0 +1,18 @@
1
+ ---
2
+ engines:
3
+ rubocop:
4
+ enabled: true
5
+ checks:
6
+ Rubocop/Style/FrozenStringLiteralComment:
7
+ enabled: false
8
+ Rubocop/Style/Documentation:
9
+ enabled: false
10
+ Rubocop/Style/ClassAndModuleChildren:
11
+ enabled: false
12
+ Rubocop/Style/SpaceInLambdaLiteral:
13
+ enabled: false
14
+ Style/SingleLineBlockParams:
15
+ enabled: false
16
+ ratings:
17
+ paths:
18
+ - "lib/**.rb"
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = "evil-struct"
3
+ gem.version = "0.0.1"
4
+ gem.author = "Andrew Kozin (nepalez)"
5
+ gem.email = "andrew.kozin@gmail.com"
6
+ gem.homepage = "https://github.com/evilmartians/evil-client"
7
+ gem.summary = "Structure with type constraints based on dry-initializer"
8
+ gem.license = "MIT"
9
+
10
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
11
+ gem.test_files = gem.files.grep(/^spec/)
12
+ gem.extra_rdoc_files = Dir["README.md", "LICENSE", "CHANGELOG.md"]
13
+
14
+ gem.required_ruby_version = ">= 2.3"
15
+
16
+ gem.add_runtime_dependency "dry-initializer", "~> 0.10"
17
+
18
+ gem.add_development_dependency "dry-types", "~> 0.9"
19
+ gem.add_development_dependency "rspec", "~> 3.0"
20
+ gem.add_development_dependency "rake", "~> 11"
21
+ gem.add_development_dependency "rubocop", "~> 0.44"
22
+ end
@@ -0,0 +1,24 @@
1
+ # Handler for shared options
2
+ class Evil::Struct::Attributes
3
+ # @private
4
+ def self.call(*args, &block)
5
+ new(*args).instance_eval(&block)
6
+ end
7
+
8
+ private
9
+
10
+ def initialize(klass, **options)
11
+ @klass = klass
12
+ @options = options
13
+ end
14
+
15
+ # Declares an attribute that shares options of the block
16
+ # @param (see Struct.attribute)
17
+ # @option (see Struct.attribute)
18
+ # @return (see Struct.attribute)
19
+ def attribute(name, type = nil, **options)
20
+ @klass.send :attribute, name, type, @options.merge(options)
21
+ end
22
+ alias_method :option, :attribute
23
+ alias_method :param, :attribute
24
+ end
@@ -0,0 +1,143 @@
1
+ require "dry-initializer"
2
+
3
+ # Nested structure with type constraints, based on the `dry-initializer` DSL
4
+ class Evil::Struct
5
+ extend Dry::Initializer::Mixin
6
+
7
+ require_relative "struct/attributes"
8
+
9
+ class << self
10
+ # Builds a struct from value that respond to `to_h` or `to_hash`
11
+ #
12
+ # @param [#to_h, #to_hash] value (nil)
13
+ # @return [Evil::Struct]
14
+ #
15
+ # @alias :call
16
+ # @alias :[]
17
+ # @alias :load
18
+ #
19
+ def new(value = {})
20
+ value if value.instance_of? self.class
21
+
22
+ hash = value if value.is_a? Hash
23
+ hash ||= value.to_h if value.respond_to? :to_h
24
+ hash ||= value.to_hash if value.respond_to? :to_hash
25
+
26
+ hash_with_symbolic_keys = hash.each_with_object({}) do |(key, val), obj|
27
+ obj[key.to_sym] = val
28
+ end
29
+ super hash_with_symbolic_keys
30
+ end
31
+ alias_method :call, :new
32
+ alias_method :[], :new
33
+ alias_method :load, :new
34
+
35
+ # Shares options between definitions made inside the block
36
+ #
37
+ # @param [Hash<Symbol, Object>] options Shared options
38
+ # @param [Proc] block Block with definitions of attributes
39
+ # @return [self] itself
40
+ #
41
+ def attributes(**options, &block)
42
+ Attributes.call(self, **options, &block)
43
+ self
44
+ end
45
+
46
+ # Returns the list of defined attributes
47
+ #
48
+ # @return [Array<Symbol>]
49
+ #
50
+ def list_of_attributes
51
+ @list_of_attributes ||= []
52
+ end
53
+
54
+ # Declares the attribute
55
+ #
56
+ # @param [#to_sym] name The name of the key
57
+ # @param [#call] type (nil) The constraint
58
+ # @option options [#to_sym] :as The name of the attribute
59
+ # @option options [Proc] :default Block returning a default value
60
+ # @option options [Boolean] :optional (nil) Whether key is optional
61
+ # @return [self]
62
+ #
63
+ # @alias :attribute
64
+ # @alias :param
65
+ #
66
+ def option(name, type = nil, as: nil, **opts)
67
+ super.tap { list_of_attributes << (as || name).to_sym }
68
+ self
69
+ end
70
+ alias_method :attribute, :option
71
+ alias_method :param, :option
72
+
73
+ private
74
+
75
+ def inherited(klass)
76
+ super
77
+ klass.instance_variable_set :@list_of_attributes, list_of_attributes.dup
78
+ end
79
+ end
80
+
81
+ # Checks an equality to other object that respond to `to_h` or `to_hash`
82
+ #
83
+ # @param [Object] other
84
+ # @return [Boolean]
85
+ #
86
+ def ==(other)
87
+ if other&.respond_to?(:to_h)
88
+ to_h == other.to_h
89
+ elsif other.respond_to?(:to_hash)
90
+ to_h == other.to_hash
91
+ else
92
+ false
93
+ end
94
+ end
95
+
96
+ # Converts nested structure to hash
97
+ #
98
+ # Makes conversion through nested hashes, arrays, enumerables, as well
99
+ # as trhough values that respond to `to_a`, `to_h`, and `to_hash`.
100
+ # Doesn't convert `nil`.
101
+ #
102
+ # @return [Hash]
103
+ #
104
+ # @alias :to_hash
105
+ # @alias :dump
106
+ #
107
+ def to_h
108
+ self.class.list_of_attributes.each_with_object({}) do |key, hash|
109
+ val = send(key)
110
+ hash[key] = hashify(val) unless val == Dry::Initializer::UNDEFINED
111
+ end
112
+ end
113
+ alias_method :to_hash, :to_h
114
+ alias_method :dump, :to_h
115
+
116
+ # @!method [](key)
117
+ # Gets the attribute value by name
118
+ #
119
+ # @param [Symbol, String] key The name of the attribute
120
+ # @return [Object] A value of the attribute
121
+ #
122
+ alias_method :[], :send
123
+
124
+ private
125
+
126
+ def hashify(value)
127
+ if value.is_a? Hash
128
+ value.each_with_object({}) { |(key, val), obj| obj[key] = hashify(val) }
129
+ elsif value.is_a? Array
130
+ value.map { |item| hashify(item) }
131
+ elsif value&.respond_to? :to_a
132
+ hashify(value.to_a)
133
+ elsif value&.respond_to? :to_h
134
+ hashify(value.to_h)
135
+ elsif value.respond_to? :to_hash
136
+ hashify(value.to_hash)
137
+ elsif value.is_a? Enumerable
138
+ value.map { |item| hashify(item) }
139
+ else
140
+ value
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,4 @@
1
+ # Namespace for gems created by Evil Martians (http://evilmartians.com)
2
+ module Evil
3
+ require_relative "evil/struct"
4
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ describe "attributes" do
4
+ before do
5
+ class Test::Foo < Evil::Struct
6
+ attribute :"some argument", as: "qux"
7
+ end
8
+ end
9
+
10
+ let(:struct) { Test::Foo.new "some argument": "bar" }
11
+
12
+ it "accessible via method" do
13
+ expect(struct.qux).to eq "bar"
14
+ end
15
+
16
+ it "accessible by symbolic key" do
17
+ expect(struct[:qux]).to eq "bar"
18
+ end
19
+
20
+ it "accessible by string key" do
21
+ expect(struct["qux"]).to eq "bar"
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe "constructor aliases" do
4
+ it ".new" do
5
+ class Test::Foo < Evil::Struct
6
+ attribute :foo
7
+ attribute :baz, default: proc { "qux" }
8
+ end
9
+
10
+ expect(Test::Foo.new foo: "bar").to eq foo: "bar", baz: "qux"
11
+ end
12
+
13
+ it ".call" do
14
+ class Test::Foo < Evil::Struct
15
+ attribute :foo
16
+ attribute :baz, default: proc { "qux" }
17
+ end
18
+
19
+ expect(Test::Foo.call foo: "bar").to eq foo: "bar", baz: "qux"
20
+ end
21
+
22
+ it ".load" do
23
+ class Test::Foo < Evil::Struct
24
+ attribute :foo
25
+ attribute :baz, default: proc { "qux" }
26
+ end
27
+
28
+ expect(Test::Foo.load foo: "bar").to eq foo: "bar", baz: "qux"
29
+ end
30
+
31
+ it ".[]" do
32
+ class Test::Foo < Evil::Struct
33
+ attribute :foo
34
+ attribute :baz, default: proc { "qux" }
35
+ end
36
+
37
+ expect(Test::Foo[foo: "bar"]).to eq foo: "bar", baz: "qux"
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe "constructor" do
4
+ before do
5
+ class Test::Foo < Evil::Struct
6
+ attribute :foo, default: proc { "qux" }
7
+ end
8
+ end
9
+
10
+ it "accepts hash with symbolic keys" do
11
+ expect(Test::Foo.new foo: "bar").to eq foo: "bar"
12
+ end
13
+
14
+ it "accepts hash with string keys" do
15
+ expect(Test::Foo.new "foo" => "bar").to eq foo: "bar"
16
+ end
17
+
18
+ it "accepts nil" do
19
+ expect(Test::Foo.new nil).to eq foo: "qux"
20
+ end
21
+
22
+ it "accepts no arguments" do
23
+ expect(Test::Foo.new).to eq foo: "qux"
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe "equalizer" do
4
+ it "uses #to_h for comparison" do
5
+ class Test::Foo < Evil::Struct
6
+ attribute :foo
7
+ end
8
+
9
+ expect(Test::Foo.new foo: "bar").to eq foo: "bar"
10
+ expect(Test::Foo.new foo: "bar").to eq double(to_h: { foo: "bar" })
11
+ end
12
+
13
+ it "makes struct not equal to nil" do
14
+ class Test::Foo < Evil::Struct
15
+ attribute :foo, optional: true
16
+ end
17
+
18
+ expect(Test::Foo.new).to eq({})
19
+ expect(Test::Foo.new).not_to eq nil
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe "hashifier" do
4
+ before do
5
+ class Test::Foo < Evil::Struct
6
+ attribute :foo
7
+ attribute :bar, optional: true
8
+ end
9
+ end
10
+
11
+ it "converts struct to hash" do
12
+ result = Test::Foo[foo: "bar", bar: "baz"].to_h
13
+
14
+ expect(result).to be_instance_of Hash
15
+ expect(result).to eq foo: "bar", bar: "baz"
16
+ end
17
+
18
+ it "hides unassigned values" do
19
+ result = Test::Foo[foo: "bar"].to_h
20
+
21
+ expect(result).to eq foo: "bar"
22
+ end
23
+
24
+ it "has alias .to_hash" do
25
+ result = Test::Foo[foo: "bar"].to_hash
26
+
27
+ expect(result).to eq foo: "bar"
28
+ end
29
+
30
+ it "has alias .dump" do
31
+ result = Test::Foo[foo: "bar"].dump
32
+
33
+ expect(result).to eq foo: "bar"
34
+ end
35
+
36
+ it "applied deeply" do
37
+ data = { foo: double(to_h: { baz: [double(to_hash: { qux: nil })] }) }
38
+
39
+ expect(Test::Foo[data].to_h).to eq foo: { baz: [{ qux: nil }] }
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe "shared options" do
4
+ it "supported via .attributes" do
5
+ class Test::Foo < Evil::Struct
6
+ attributes type: Dry::Types["strict.string"], default: proc { "bar" } do
7
+ attribute :foo
8
+ attribute :baz, default: proc { "qux" }
9
+ end
10
+ end
11
+
12
+ expect(Test::Foo.new).to eq foo: "bar", baz: "qux"
13
+ expect { Test::Foo.new foo: 1 }.to raise_error(TypeError)
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require "pry"
3
+ rescue LoadError
4
+ nil
5
+ end
6
+
7
+ require "evil-struct"
8
+ require "dry-types"
9
+
10
+ RSpec.configure do |config|
11
+ config.order = :random
12
+ config.filter_run focus: true
13
+ config.run_all_when_everything_filtered = true
14
+
15
+ # Prepare the Test namespace for constants defined in specs
16
+ config.around(:each) do |example|
17
+ Test = Class.new(Module)
18
+ example.run
19
+ Object.send :remove_const, :Test
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evil-struct
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kozin (nepalez)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-initializer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.44'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.44'
83
+ description:
84
+ email: andrew.kozin@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files:
88
+ - README.md
89
+ files:
90
+ - ".codeclimate.yml"
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".rubocop.yml"
94
+ - ".travis.yml"
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - codeclimate.yml
100
+ - evil-struct.gemspec
101
+ - lib/evil-struct.rb
102
+ - lib/evil/struct.rb
103
+ - lib/evil/struct/attributes.rb
104
+ - spec/features/attributes_spec.rb
105
+ - spec/features/constructor_aliases_spec.rb
106
+ - spec/features/constructor_arguments_spec.rb
107
+ - spec/features/equalizer_spec.rb
108
+ - spec/features/hashifier_spec.rb
109
+ - spec/features/shared_options_spec.rb
110
+ - spec/spec_helper.rb
111
+ homepage: https://github.com/evilmartians/evil-client
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '2.3'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.6.4
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Structure with type constraints based on dry-initializer
135
+ test_files:
136
+ - spec/features/attributes_spec.rb
137
+ - spec/features/constructor_aliases_spec.rb
138
+ - spec/features/constructor_arguments_spec.rb
139
+ - spec/features/equalizer_spec.rb
140
+ - spec/features/hashifier_spec.rb
141
+ - spec/features/shared_options_spec.rb
142
+ - spec/spec_helper.rb
143
+ has_rdoc: