sinclair 1.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0edfe38e5f22be2399222b5534075f9df89c8751
4
+ data.tar.gz: baca00ae7d1c378fc8dcd1fdebbc9cdb8d33a4df
5
+ SHA512:
6
+ metadata.gz: 5bf435dcd30518a56afed24ee5e53f8969173fe18212980763bb991836c621cf8127d3140a681cbeb4e3ec6945a08c4446ba48adb8e5acd207621ccddba9e62f
7
+ data.tar.gz: d8336f8b958e90d2ec5bb19d598fe07ca484b7b0406525d18bfd780241d1a0d872203e4577ef9d36857fcb46c63c0896dc592c3d0c013feb54e0b827aebe9d78
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: circleci/ruby:2.4.1
6
+ steps:
7
+ - checkout
8
+ - run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
9
+ - run: chmod +x ./cc-test-reporter
10
+ - run: ./cc-test-reporter before-build
11
+ - run: bundle install
12
+ - run: bundle exec rspec
13
+ - run: ./cc-test-reporter after-build --exit-code $?
@@ -0,0 +1,4 @@
1
+ coverages
2
+ pkg
3
+ Gemfile.lock
4
+ coverage
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Favini
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 all
13
+ 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 THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,152 @@
1
+ Sinclair
2
+ ========
3
+
4
+ This gem helps the creation of complex concern with class methods
5
+
6
+ Getting started
7
+ ---------------
8
+ 1. Installation
9
+ - Install it
10
+
11
+ ```ruby
12
+ gem install sinclair
13
+ ```
14
+
15
+ - Or add Sinclairn to your `Gemfile` and `bundle install`:
16
+
17
+ ```ruby
18
+ gem 'sinclair'
19
+ ```
20
+
21
+ ```bash
22
+ bundle install sinclair
23
+ ```
24
+
25
+ 2. Using it:
26
+ The concern builder can actully be used in two ways, as an stand alone object capable of
27
+ adding methods to your class or by extending it for more complex logics
28
+
29
+ - Stand Alone usage:
30
+ ```ruby
31
+ class Clazz
32
+ end
33
+
34
+ builder = Sinclair.new(Clazz)
35
+
36
+ builder.add_method(:twenty, '10 + 10')
37
+ builder.add_method(:eighty) { 4 * twenty }
38
+ builder.build
39
+
40
+ instance = Clazz.new
41
+
42
+ puts "Twenty => #{instance.twenty}"
43
+ puts "Eighty => #{instance.eighty}"
44
+ ```
45
+
46
+ ```string
47
+ Twenty => 20
48
+ Eighty => 80
49
+ ```
50
+
51
+ - Extending the builder
52
+
53
+ ```ruby
54
+ class ValidationBuilder < Sinclair
55
+ delegate :expected, to: :options_object
56
+
57
+ def initialize(clazz, options={})
58
+ super
59
+ end
60
+
61
+ def add_validation(field)
62
+ add_method("#{field}_valid?", "#{field}.is_a?#{expected}")
63
+ end
64
+
65
+ def add_accessors(fields)
66
+ clazz.send(:attr_accessor, *fields)
67
+ end
68
+ end
69
+
70
+ module MyConcern
71
+ extend ActiveSupport::Concern
72
+
73
+ class_methods do
74
+ def validate(*fields, expected_class)
75
+ builder = ::ValidationBuilder.new(self, expected: expected_class)
76
+
77
+ validatable_fields.concat(fields)
78
+ builder.add_accessors(fields)
79
+
80
+ fields.each do |field|
81
+ builder.add_validation(field)
82
+ end
83
+
84
+ builder.build
85
+ end
86
+
87
+ def validatable_fields
88
+ @validatable_fields ||= []
89
+ end
90
+ end
91
+
92
+ def valid?
93
+ self.class.validatable_fields.all? do |field|
94
+ public_send("#{field}_valid?")
95
+ end
96
+ end
97
+ end
98
+
99
+ class MyClass
100
+ include MyConcern
101
+ validate :name, :surname, String
102
+ validate :age, :legs, Integer
103
+
104
+ def initialize(name: nil, surname: nil, age: nil, legs: nil)
105
+ @name = name
106
+ @surname = surname
107
+ @age = age
108
+ @legs = legs
109
+ end
110
+ end
111
+
112
+ instance = MyClass.new
113
+ ```
114
+
115
+ the instance will respond to the methods
116
+ ```name``` ```name=``` ```name_valid?```
117
+ ```surname``` ```surname=``` ```surname_valid?```
118
+ ```age``` ```age=``` ```age_valid?```
119
+ ```legs``` ```legs=``` ```legs_valid?```
120
+ ```valid?```
121
+
122
+ ```ruby
123
+ valid_object = MyClass.new(
124
+ name: :name,
125
+ surname: 'surname',
126
+ age: 20,
127
+ legs: 2
128
+ )
129
+ valid_object.valid?
130
+ ```
131
+
132
+ returns
133
+
134
+ ```
135
+ true
136
+ ```
137
+
138
+ ```ruby
139
+ invalid_object = MyClass.new(
140
+ name: 'name',
141
+ surname: 'surname',
142
+ age: 20,
143
+ legs: 2
144
+ )
145
+ invalid_object.valid?
146
+ ```
147
+
148
+ returns
149
+
150
+ ```
151
+ false
152
+ ```
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task :default => :spec
5
+ task test: :spec
@@ -0,0 +1,18 @@
1
+ version: '2'
2
+ services:
3
+ base: &base
4
+ image: ruby:2.4.0
5
+ working_dir: /home/app/sinclair
6
+ volumes:
7
+ - .:/home/app/sinclair
8
+ - sinclair_gems_2_4_0:/usr/local/bundle
9
+
10
+ #################### CONTAINERS ####################
11
+
12
+ sinclair:
13
+ <<: *base
14
+ container_name: sinclair
15
+ command: /bin/bash -c 'bundle install && bundle exec rspec'
16
+
17
+ volumes:
18
+ sinclair_gems_2_4_0:
@@ -0,0 +1,38 @@
1
+ require 'active_support'
2
+ require 'active_support/all'
3
+
4
+ class Sinclair
5
+ require 'sinclair/options_parser'
6
+
7
+ autoload :VERSION, 'sinclair/version'
8
+ autoload :MethodDefinition, 'sinclair/method_definition'
9
+
10
+ include OptionsParser
11
+
12
+ attr_reader :clazz
13
+
14
+ def initialize(clazz, options = {})
15
+ @clazz = clazz
16
+ @options = options
17
+ end
18
+
19
+ def build
20
+ definitions.each do |definition|
21
+ definition.build(clazz)
22
+ end
23
+ end
24
+
25
+ def add_method(name, code = nil, &block)
26
+ definitions << MethodDefinition.new(name, code, &block)
27
+ end
28
+
29
+ def eval_and_add_method(name, &block)
30
+ add_method(name, instance_eval(&block))
31
+ end
32
+
33
+ private
34
+
35
+ def definitions
36
+ @definitions ||= []
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ class Sinclair::MethodDefinition
2
+ attr_reader :name, :code, :block
3
+
4
+ def initialize(name, code = nil, &block)
5
+ @name = name
6
+ @code = code
7
+ @block = block
8
+ end
9
+
10
+ def build(clazz)
11
+ if code.is_a?(String)
12
+ build_code_method(clazz)
13
+ else
14
+ build_block_method(clazz)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def build_block_method(clazz)
21
+ clazz.send(:define_method, name, block)
22
+ end
23
+
24
+ def build_code_method(clazz)
25
+ clazz.module_eval(code_definition, __FILE__, __LINE__ + 1)
26
+ end
27
+
28
+ def code_definition
29
+ <<-CODE
30
+ def #{name}
31
+ #{code}
32
+ end
33
+ CODE
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Sinclair::OptionsParser
2
+ extend ActiveSupport::Concern
3
+
4
+ attr_reader :options
5
+
6
+ def options_object
7
+ @options_object ||= OpenStruct.new options
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class Sinclair
2
+ VERSION = '1.0.0'
3
+ end
4
+
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sinclair/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'sinclair'
8
+ gem.version = Sinclair::VERSION
9
+ gem.authors = ["DarthJee"]
10
+ gem.email = ["darthjee@gmail.com"]
11
+ gem.homepage = 'https://github.com/darthjee/sinclair'
12
+ gem.description = 'Gem for easy concern creation'
13
+ gem.summary = gem.description
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|gem|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency 'activesupport', '~> 5.2.0'
21
+
22
+ gem.add_development_dependency 'bundler', '~> 1.6'
23
+ gem.add_development_dependency 'rake', '~> 12.0.0'
24
+ gem.add_development_dependency 'rspec', '~> 2.14'
25
+ gem.add_development_dependency 'simplecov', '~> 0.16.1'
26
+ gem.add_development_dependency 'pry-nav'
27
+ end
28
+
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe MyClass do
4
+ subject { clazz.new(attributes) }
5
+ let(:clazz) { MyClass }
6
+ let(:name) { 'name' }
7
+ let(:age) { 20 }
8
+ let(:attributes) do
9
+ {
10
+ name: name,
11
+ surname: 'surname',
12
+ age: age,
13
+ legs: 2
14
+ }
15
+ end
16
+
17
+ %i(name surname age legs).each do |field|
18
+ it do
19
+ expect(subject).to respond_to(field)
20
+ end
21
+
22
+ it do
23
+ expect(subject).to respond_to("#{field}_valid?")
24
+ end
25
+ end
26
+
27
+ it do
28
+ expect(subject).to respond_to(:valid?)
29
+ end
30
+
31
+ describe '#valid?' do
32
+ it do
33
+ expect(subject).to be_valid
34
+ end
35
+
36
+ context 'when a string attribute is a symbol' do
37
+ let(:name) { :name }
38
+ it do
39
+ expect(subject).not_to be_valid
40
+ end
41
+ end
42
+
43
+ context 'when an attribute is nil' do
44
+ let(:age) { nil }
45
+ it do
46
+ expect(subject).not_to be_valid
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Stand Alone' do
4
+ let(:instance) { clazz.new }
5
+ let(:clazz) { Class.new }
6
+ let(:builder) { Sinclair.new(clazz) }
7
+
8
+ before do
9
+ builder.add_method(:twenty, '10 + 10')
10
+ builder.add_method(:eighty) { 4 * twenty }
11
+ builder.build
12
+ end
13
+
14
+ it 'knows how to add string defined methods' do
15
+ expect("Twenty => #{instance.twenty}").to eq('Twenty => 20')
16
+ end
17
+
18
+ it 'knows how to add block defined methods' do
19
+ expect("Eighty => #{instance.eighty}").to eq('Eighty => 80')
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sinclair::MethodDefinition do
4
+ let(:clazz) { Class.new }
5
+ let(:instance) { clazz.new }
6
+
7
+ describe '#build' do
8
+ let(:method_name) { :the_method }
9
+
10
+ context 'when method was defined with an string' do
11
+ let(:code) { '"Self ==> " + self.to_s' }
12
+
13
+ subject { described_class.new(method_name, code) }
14
+
15
+ before do
16
+ subject.build(clazz)
17
+ end
18
+
19
+ it 'adds the method to the clazz instance' do
20
+ expect(instance).to respond_to(method_name)
21
+ end
22
+
23
+ it 'evaluates return of the method within the instance context' do
24
+ expect(instance.the_method).to eq("Self ==> #{instance}")
25
+ end
26
+ end
27
+
28
+ context 'when method was defined with a block' do
29
+ subject do
30
+ described_class.new(method_name) do
31
+ "Self ==> " + self.to_s
32
+ end
33
+ end
34
+
35
+ before do
36
+ subject.build(clazz)
37
+ end
38
+
39
+ it 'adds the method to the clazz instance' do
40
+ expect(instance).to respond_to(method_name)
41
+ end
42
+
43
+ it 'evaluates return of the method within the instance context' do
44
+ expect(instance.the_method).to eq("Self ==> #{instance}")
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sinclair::OptionsParser do
4
+ let(:clazz) { described_class::Dummy }
5
+ let(:switched) { true }
6
+ let(:value_1) { 'value1' }
7
+ let(:options) { { switch: switched, option_1: value_1, option_2: 2} }
8
+
9
+ subject do
10
+ clazz.new(options)
11
+ end
12
+
13
+ it 'enables the given options to be acced' do
14
+ expect(subject.the_method).to eq('The value is value1')
15
+ end
16
+
17
+ context 'when changing the options' do
18
+ let(:switched) { false }
19
+
20
+ it 'enables the given options to be acced' do
21
+ expect(subject.the_method).to eq('The value is not value1 but 2')
22
+ end
23
+ end
24
+
25
+ context 'when there is an option missing' do
26
+ let(:options) { { option_1: 'value1', option_2: 2} }
27
+
28
+ it do
29
+ expect { subject.the_method }.not_to raise_error
30
+ end
31
+
32
+ it 'considers is to be nil' do
33
+ expect(subject.the_method).to eq('missing option')
34
+ end
35
+ end
36
+
37
+ context 'when changing the options before the option call' do
38
+ before do
39
+ subject
40
+ options[:switch] = false
41
+ end
42
+
43
+ it 'does not reevaluate the options' do
44
+ expect(subject.the_method).to eq('The value is value1')
45
+ end
46
+
47
+ context 'when the option value is another object on its own' do
48
+ let(:value_1) { { key: 'value' } }
49
+ before do
50
+ subject
51
+ options[:option_1][:key] = 100
52
+ end
53
+
54
+ it 'does not reevaluate the options' do
55
+ expect(subject.the_method).to eq('The value is {:key=>"value"}')
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sinclair do
4
+ let(:options) { {} }
5
+ let(:instance) { dummy_class.new }
6
+ let(:dummy_class) { Class.new }
7
+ let(:builder_class) { described_class }
8
+ subject { builder_class.new(dummy_class, options) }
9
+
10
+ describe '#add_method' do
11
+ context 'when extending the class' do
12
+ let(:builder_class) { described_class::DummyBuilder }
13
+
14
+ before do
15
+ subject.init
16
+ subject.build
17
+ end
18
+
19
+ context 'when describing a method with block' do
20
+ it 'creates a method with the block' do
21
+ expect(instance.blocked).to eq(1)
22
+ end
23
+ end
24
+
25
+ context 'when describing a method with string' do
26
+ it 'creates a method using the string definition' do
27
+ expect(instance.defined).to eq(1)
28
+ expect(instance.defined).to eq(2)
29
+ end
30
+ end
31
+
32
+ context 'when passing options' do
33
+ let(:options) { { increment: 2 } }
34
+ it 'parses the options' do
35
+ expect(instance.defined).to eq(2)
36
+ expect(instance.defined).to eq(4)
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'when using the builder without extending' do
42
+ context 'when declaring a method with a block' do
43
+ before do
44
+ subject.add_method(:blocked) { 1 }
45
+ subject.add_method(:blocked) { 2 }
46
+ subject.build
47
+ end
48
+
49
+ it 'respect the order of method addtion' do
50
+ expect(instance.blocked).to eq(2)
51
+ end
52
+ end
53
+
54
+ context 'when declaring a method string' do
55
+ before do
56
+ subject.add_method(:string, '1')
57
+ subject.add_method(:string, '2')
58
+ subject.build
59
+ end
60
+
61
+ it 'respect the order of method addtion' do
62
+ expect(instance.string).to eq(2)
63
+ end
64
+ end
65
+
66
+ context 'when declaring a method using string or block' do
67
+ context 'when declaring the block first' do
68
+ before do
69
+ subject.add_method(:value) { 1 }
70
+ subject.add_method(:value, '2')
71
+ subject.build
72
+ end
73
+
74
+ it 'respect the order of method addtion' do
75
+ expect(instance.value).to eq(2)
76
+ end
77
+ end
78
+
79
+ context 'when declaring the string first' do
80
+ before do
81
+ subject.add_method(:value, '1')
82
+ subject.add_method(:value) { 2 }
83
+ subject.build
84
+ end
85
+
86
+ it 'respect the order of method addtion' do
87
+ expect(instance.value).to eq(2)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#eval_and_add_method' do
95
+ context 'when defining the method once' do
96
+ before do
97
+ subject.add_method(:value, "@value ||= 0")
98
+ subject.eval_and_add_method(:defined) { "@value = value + #{ options_object.increment || 1 }" }
99
+ subject.build
100
+ end
101
+
102
+ it 'creates a method using the string definition' do
103
+ expect(instance.defined).to eq(1)
104
+ expect(instance.defined).to eq(2)
105
+ end
106
+
107
+ context 'when passing options' do
108
+ let(:options) { { increment: 2 } }
109
+
110
+ it 'parses the options' do
111
+ expect(instance.defined).to eq(2)
112
+ expect(instance.defined).to eq(4)
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'when redefining a method already added' do
118
+ before do
119
+ subject.add_method(:value, "@value ||= 0")
120
+ subject.add_method(:defined, "100")
121
+ subject.eval_and_add_method(:defined) { "@value = value + #{ options_object.increment || 1 }" }
122
+ subject.build
123
+ end
124
+
125
+ it 'redefines it' do
126
+ expect(instance.defined).to eq(1)
127
+ expect(instance.defined).to eq(2)
128
+ end
129
+ end
130
+
131
+ context 'when readding it' do
132
+ before do
133
+ subject.add_method(:value, "@value ||= 0")
134
+ subject.eval_and_add_method(:defined) { "@value = value + #{ options_object.increment || 1 }" }
135
+ subject.add_method(:defined, "100")
136
+ subject.build
137
+ end
138
+
139
+ it 'redefines it' do
140
+ expect(instance.defined).to eq(100)
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,25 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.profiles.define 'gem' do
4
+ add_filter '/spec/'
5
+ end
6
+
7
+ SimpleCov.start 'gem'
8
+
9
+ require 'sinclair'
10
+ require 'pry-nav'
11
+
12
+ support_files = File.expand_path("spec/support/**/*.rb")
13
+ Dir[support_files].each { |file| require file }
14
+
15
+ RSpec.configure do |config|
16
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
+ config.run_all_when_everything_filtered = true
18
+ config.filter_run :focus
19
+ config.filter_run_excluding :integration unless ENV['ALL']
20
+
21
+ config.order = 'random'
22
+
23
+ config.before do
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ require 'active_support'
2
+
3
+ module FixtureHelpers
4
+ def load_fixture_file(filename)
5
+ File.read (['./spec/', 'fixtures', filename].join('/'))
6
+ end
7
+
8
+ def load_json_fixture_file(filename)
9
+ cached_json_fixture_file(filename)
10
+ end
11
+
12
+ private
13
+
14
+ def cached_json_fixture_file(filename)
15
+ ActiveSupport::JSON.decode(load_fixture_file(filename))
16
+ end
17
+ end
18
+
19
+ RSpec.configuration.include FixtureHelpers
@@ -0,0 +1,7 @@
1
+ class Sinclair::DummyBuilder < Sinclair
2
+ def init
3
+ add_method(:blocked) { 1 }
4
+ add_method(:defined, "@value = value + #{ options_object.try(:increment) || 1 }")
5
+ add_method(:value, "@value ||= 0")
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ class Sinclair
2
+ class OptionsParser::Dummy
3
+ include OptionsParser
4
+
5
+ def initialize(options)
6
+ @options = options.deep_dup
7
+ end
8
+
9
+ def the_method
10
+ return 'missing option' if options_object.switch.nil?
11
+
12
+ if options_object.switch
13
+ "The value is #{options_object.option_1}"
14
+ else
15
+ "The value is not #{options_object.option_1} but #{options_object.option_2}"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'my_concern'
2
+
3
+ class MyClass
4
+ include MyConcern
5
+ validate :name, :surname, String
6
+ validate :age, :legs, Integer
7
+
8
+ def initialize(name: nil, surname: nil, age: nil, legs: nil)
9
+ @name = name
10
+ @surname = surname
11
+ @age = age
12
+ @legs = legs
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'validator_builder'
2
+
3
+ module MyConcern
4
+ extend ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ def validate(*fields, expected_class)
8
+ builder = ::ValidationBuilder.new(self, expected: expected_class)
9
+
10
+ validatable_fields.concat(fields)
11
+ builder.add_accessors(fields)
12
+
13
+ fields.each do |field|
14
+ builder.add_validation(field)
15
+ end
16
+
17
+ builder.build
18
+ end
19
+
20
+ def validatable_fields
21
+ @validatable_fields ||= []
22
+ end
23
+ end
24
+
25
+ def valid?
26
+ self.class.validatable_fields.all? do |field|
27
+ public_send("#{field}_valid?")
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ class ValidationBuilder < Sinclair
2
+ delegate :expected, to: :options_object
3
+
4
+ def initialize(clazz, options={})
5
+ super
6
+ end
7
+
8
+ def add_validation(field)
9
+ add_method("#{field}_valid?", "#{field}.is_a?#{expected}")
10
+ end
11
+
12
+ def add_accessors(fields)
13
+ clazz.send(:attr_accessor, *fields)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinclair
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - DarthJee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 12.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 12.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.16.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.16.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-nav
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Gem for easy concern creation
98
+ email:
99
+ - darthjee@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".circleci/config.yml"
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - Gemfile
108
+ - LICENSE
109
+ - README.md
110
+ - Rakefile
111
+ - docker-compose.yml
112
+ - lib/sinclair.rb
113
+ - lib/sinclair/method_definition.rb
114
+ - lib/sinclair/options_parser.rb
115
+ - lib/sinclair/version.rb
116
+ - sinclair.gemspec
117
+ - spec/integration/readme/my_class_spec.rb
118
+ - spec/integration/readme_spec.rb
119
+ - spec/lib/sinclair/method_definition_spec.rb
120
+ - spec/lib/sinclair/options_parser_spec.rb
121
+ - spec/lib/sinclair_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/support/fixture_helpers.rb
124
+ - spec/support/models/dummy_builder.rb
125
+ - spec/support/models/dummy_options_parser.rb
126
+ - spec/support/models/my_class.rb
127
+ - spec/support/models/my_concern.rb
128
+ - spec/support/models/validator_builder.rb
129
+ homepage: https://github.com/darthjee/sinclair
130
+ licenses: []
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.6.11
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Gem for easy concern creation
152
+ test_files: []