sinclair 1.0.0

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