composed_validations 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: a3255cb3f57d5dd1001ea94244bb3d32fe33dd05
4
+ data.tar.gz: fbe1c3d47be05fa2dacd7a9de8e4c28f133ac193
5
+ SHA512:
6
+ metadata.gz: 39902f36a6fd5a32f25f9b313962c29cd3d41b117458cf26ecdbfd4715b7922a457510a5cfcf7c5577ad474b146e2b501004545c2a1eba467a592d7458afe3f3
7
+ data.tar.gz: 8f41a206b1be58839528ada156086ef999dfbfc0f06df24695616b427b76d70615ccd7350e5425f56ce27fc772a8420768058176ac2b49af60c3c41de87aaf15
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in composed_validations.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # ComposedValidations
2
+ [![Circle
3
+ CI](https://circleci.com/gh/terrellt/composed_validations.svg?style=svg)](https://circleci.com/gh/terrellt/composed_validations)
4
+
5
+ This gem's purpose is to get around having to set validations on your base
6
+ ActiveModel::Model class. Have you ever wanted to conditionally set validations
7
+ based on business logic? Maybe this gem will help.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'composed_validations'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install composed_validations
24
+
25
+ ## Usage
26
+
27
+ This gem works on the premise of a few simple interfaces:
28
+
29
+ ### Decorated Object
30
+
31
+ There's an object which responds to the #valid? method, as used by
32
+ ActiveModel::Validations, that you'd like to decorate functionality on to which
33
+ has a set of accessible properties.
34
+
35
+ ```ruby
36
+ class MyObject
37
+ include ActiveModel::Validations
38
+ attr_accessor :title, :description
39
+ end
40
+ ```
41
+
42
+ ### Validators
43
+
44
+ Validators are objects which takes the result of using a property accessor and
45
+ says whether or not it's valid. It responds to `valid?(value)` and `message`(the
46
+ message which gets added to errors if this is not valid.)
47
+
48
+ ```ruby
49
+ class StringIsBob
50
+ def valid?(value)
51
+ value.to_s == "Bob"
52
+ end
53
+
54
+ def message
55
+ "needs to be the string 'Bob'"
56
+ end
57
+ end
58
+ ```
59
+
60
+ ### Decorating One Property
61
+
62
+ You can add these validations to an object with the following:
63
+
64
+ ```ruby
65
+ m = MyObject.new
66
+ m = ComposedValidators::WithValidatedProperty.new(m, :title, StringIsBob.new)
67
+ m.valid? # => false
68
+ m.title = "Bob"
69
+ m.valid? # => true
70
+ ```
71
+
72
+ ### Decorating Multiple Properties
73
+
74
+ If you need to decorate multiple validators onto one property or multiple
75
+ properties at once there is the DecorateProperties object. It works as follows:
76
+
77
+ ```ruby
78
+ m = MyObject.new
79
+ m = ComposedValidators::DecorateProperties.new(m, {:title => StringIsBob.new,
80
+ :description => StringIsBob.new})
81
+ m.valid? # => false
82
+ m.title = "Bob"
83
+ m.valid? # => false
84
+ m.description = "Bob"
85
+ m.valid? # => true
86
+ ```
87
+
88
+ ### OR Validations
89
+
90
+ Sometimes you want a property to be valid if one or more validations are true,
91
+ rather than all. To accomplish this we've provided an OrValidator composite
92
+ object. It can be used as follows:
93
+
94
+ ```ruby
95
+ m = Myobject.new
96
+ composed_validator = ComposedValidators::OrValidator.new([StringIsBob.new,
97
+ StringIsJoe.new])
98
+ m = ComposedValidators::WithValidatedProperty.new(m, :title, composed_validator)
99
+ m.valid? # => false
100
+ m.title = "Bob"
101
+ m.valid? # => true
102
+ m.title = "Joe"
103
+ m.valid? # => true
104
+ ```
105
+
106
+ ## Contributing
107
+
108
+ 1. Fork it ( https://github.com/[my-github-username]/composed_validations/fork )
109
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
110
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
111
+ 4. Push to the branch (`git push origin my-new-feature`)
112
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/circle.yml ADDED
@@ -0,0 +1,3 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.2.0
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'composed_validations/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "composed_validations"
8
+ spec.version = ComposedValidations::VERSION
9
+ spec.authors = ["Trey Terrell"]
10
+ spec.email = ["trey.terrell@oregonstate.edu"]
11
+ spec.summary = %q{Composes validations onto properties of an object.}
12
+ spec.homepage = "http://github.com/terrellt/composed_validations"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+ spec.add_dependency "attr_extras"
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_development_dependency "pry-byebug"
25
+ spec.add_development_dependency "byebug"
26
+ spec.add_development_dependency "activemodel"
27
+ end
@@ -0,0 +1,22 @@
1
+ require "composed_validations/version"
2
+ require 'delegate'
3
+ require 'attr_extras'
4
+
5
+ module ComposedValidations
6
+ autoload :WithValidatedProperty, "composed_validations/with_validated_property"
7
+ autoload :DecorateProperties, "composed_validations/decorate_properties"
8
+ autoload :PropertyValidator, "composed_validations/property_validator"
9
+ autoload :OrValidator, "composed_validations/or_validator"
10
+ autoload :OrStringJoiner, "composed_validations/or_string_joiner"
11
+ autoload :ValidatedProperty, "composed_validations/validated_property"
12
+
13
+ def ValidatedProperty(value)
14
+ if value.kind_of? ValidatedProperty
15
+ value
16
+ else
17
+ ValidatedProperty.new(value.to_sym, value.to_sym)
18
+ end
19
+ end
20
+
21
+ module_function :ValidatedProperty
22
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # Takes a resource and a hash with properties as the keys and validators as the
3
+ # values and decorates those validations onto the resource.
4
+ module ComposedValidations
5
+ class DecorateProperties
6
+ pattr_initialize :resource, :property_mapper
7
+
8
+ def run
9
+ temp_resource = resource
10
+ property_mapper.to_a.map{|x| PropertyValidator.new(*x) }.each do |p|
11
+ temp_resource = p.decorate_resource(temp_resource)
12
+ end
13
+ temp_resource
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,23 @@
1
+ module ComposedValidations
2
+ class OrStringJoiner
3
+ attr_reader :strings, :last_two
4
+ def initialize(*strings)
5
+ @strings = strings
6
+ @last_two = @strings.pop(2)
7
+ end
8
+
9
+ def to_s
10
+ [first_elements_string, last_two_elements_string].join(", ").gsub(/^, /,'')
11
+ end
12
+
13
+ private
14
+
15
+ def first_elements_string
16
+ strings.join(", ")
17
+ end
18
+
19
+ def last_two_elements_string
20
+ last_two.join(" or ")
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module ComposedValidations
2
+ class OrValidator
3
+ pattr_initialize :validators
4
+
5
+ def valid?(record)
6
+ validators.any? do |validator|
7
+ validator.valid?(record)
8
+ end
9
+ end
10
+
11
+ def message
12
+ @message ||= OrStringJoiner.new(validators.map(&:message)).to_s
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,16 @@
1
+ module ComposedValidations
2
+ class PropertyValidator
3
+ attr_reader :property, :validators
4
+ def initialize(property, validators)
5
+ @property = property
6
+ @validators = Array(validators)
7
+ end
8
+
9
+ def decorate_resource(resource)
10
+ validators.each do |validator|
11
+ resource = WithValidatedProperty.new(resource, property, validator)
12
+ end
13
+ resource
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module ComposedValidations
2
+ class ValidatedProperty
3
+ vattr_initialize :validated_property, :property_accessor
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module ComposedValidations
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,29 @@
1
+ module ComposedValidations
2
+ class WithValidatedProperty < ::SimpleDelegator
3
+ attr_reader :property, :validator
4
+ def initialize(resource, property, validator)
5
+ super(resource)
6
+ @property = ComposedValidations::ValidatedProperty(property)
7
+ @validator = validator
8
+ end
9
+
10
+ def valid?(*args)
11
+ __getobj__.valid?(*args)
12
+ unless validator.valid?(result)
13
+ errors.add(property.validated_property, validator.message)
14
+ end
15
+ errors.blank?
16
+ end
17
+
18
+ def save(*args)
19
+ return false unless valid?
20
+ __getobj__.save(*args)
21
+ end
22
+
23
+ private
24
+
25
+ def result
26
+ __send__(property.property_accessor)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ComposedValidations::DecorateProperties do
4
+ subject { described_class.new(resource, property_mapper) }
5
+ let(:resource) { double("ValidatableAsset") }
6
+ let(:property_mapper) do
7
+ {
8
+ :title => [
9
+ validator,
10
+ validator2
11
+ ]
12
+ }
13
+ end
14
+ let(:validator) { fake_validator(true) }
15
+ let(:validator2) { fake_validator(true) }
16
+
17
+ describe "#run" do
18
+ before do
19
+ allow(ComposedValidations::WithValidatedProperty).to receive(:new).and_call_original
20
+ end
21
+ it "should decorate the given properties" do
22
+ result = subject.run
23
+
24
+ expect(ComposedValidations::WithValidatedProperty).to have_received(:new).with(resource, :title, validator)
25
+ expect(ComposedValidations::WithValidatedProperty).to have_received(:new).with(result.__getobj__, :title, validator2)
26
+ end
27
+ end
28
+
29
+ def fake_validator(result=true)
30
+ v = double("Validator")
31
+ allow(v).to receive(:valid?).with(resource).and_return(result)
32
+ allow(v).to receive(:message).and_return("has a bad validation")
33
+ v
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ComposedValidations::OrStringJoiner do
4
+ subject { described_class.new(*strings) }
5
+ context "when there's two strings" do
6
+ let(:strings) { ["one", "two"] }
7
+ it "should join with or" do
8
+ expect(subject.to_s).to eq "one or two"
9
+ end
10
+ end
11
+ context "when there's three strings" do
12
+ let(:strings) { ["one", "two", "three"] }
13
+ it "should join with a comma and or" do
14
+ expect(subject.to_s).to eq "one, two or three"
15
+ end
16
+ end
17
+ context "when there's four strings" do
18
+ let(:strings) { ["one", "two", "three", "four"] }
19
+ it "should join nicely" do
20
+ expect(subject.to_s).to eq "one, two, three or four"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ComposedValidations::OrValidator do
4
+ subject { described_class.new(validators) }
5
+ let(:validators) { [ validator_1, validator_2 ] }
6
+ let(:validator_1) { mock_validator(valid: true) }
7
+ let(:validator_2) { mock_validator(valid: true) }
8
+
9
+ describe "#valid?" do
10
+ let(:value) { double("value") }
11
+ let(:result) { subject.valid?(value) }
12
+ context "when both validators are valid" do
13
+ it "should return true" do
14
+ expect(result).to eq true
15
+ end
16
+ end
17
+ context "when one is valid" do
18
+ let(:validator_2) { mock_validator(valid: false) }
19
+ it "should return true" do
20
+ expect(result).to eq true
21
+ end
22
+ end
23
+ context "when both are invalid" do
24
+ let(:validator_1) { mock_validator(valid: false) }
25
+ let(:validator_2) { mock_validator(valid: false) }
26
+ it "should return false" do
27
+ expect(result).to eq false
28
+ end
29
+ end
30
+ describe "#message" do
31
+ it "should combine the two validators' messages" do
32
+ expect(subject.message).to eq "message or message"
33
+ end
34
+ end
35
+ end
36
+
37
+ def mock_validator(valid:)
38
+ i = double("validator")
39
+ allow(i).to receive(:valid?).and_return(valid)
40
+ allow(i).to receive(:message).and_return("message")
41
+ i
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ComposedValidations::ValidatedProperty do
4
+ subject { described_class.new(:validated_property, :property_accessor) }
5
+ describe "#validated_property" do
6
+ it "should return the validated property" do
7
+ expect(subject.validated_property).to eq :validated_property
8
+ end
9
+ end
10
+ describe "#property_accessor" do
11
+ it "should return the property accessor" do
12
+ expect(subject.property_accessor).to eq :property_accessor
13
+ end
14
+ end
15
+
16
+ describe "Caster" do
17
+ subject { ComposedValidations::ValidatedProperty(value) }
18
+ context "when given a string" do
19
+ let(:value) { "test" }
20
+ it "should return with both attributes set to its symbol" do
21
+ expect(subject.validated_property).to eq :test
22
+ expect(subject.property_accessor).to eq :test
23
+ end
24
+ end
25
+ context "when given a validated property" do
26
+ let(:value) { described_class.new(:test, :test2) }
27
+ it "should return it back" do
28
+ expect(subject).to eq value
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ComposedValidations::WithValidatedProperty do
4
+ subject { described_class.new(asset, property, validator) }
5
+ let(:asset) { double("Object") }
6
+ let(:property) { :title }
7
+ let(:validator) { double("Validator") }
8
+ let(:result) { double("result") }
9
+ let(:errors) { double("errors_object") }
10
+ before do
11
+ allow(asset).to receive(:title).and_return(result)
12
+ allow(asset).to receive(:errors).and_return(errors)
13
+ allow(asset).to receive(:valid?).and_return(true)
14
+ allow(errors).to receive(:add)
15
+ # Errors isn't blank if it's received add.
16
+ allow(errors).to receive(:blank?) do
17
+ !!!RSpec::Mocks::Matchers::HaveReceived.new(:add).matches?(errors)
18
+ end
19
+ allow(validator).to receive(:message).and_return("is so awful")
20
+ end
21
+
22
+ describe "#valid?" do
23
+ let(:valid) { true }
24
+ let(:valid_result) { subject.valid? }
25
+ before do
26
+ allow(validator).to receive(:valid?).with(result).and_return(valid)
27
+ valid_result
28
+ end
29
+ it "should call asset.valid?" do
30
+ expect(asset).to have_received(:valid?)
31
+ end
32
+ context "when validator returns true" do
33
+ it "should not add any errors" do
34
+ expect(errors).not_to have_received(:add)
35
+ end
36
+ it "should return true" do
37
+ expect(valid_result).to eq true
38
+ end
39
+ end
40
+ context "when passing in a ValidatedProperty" do
41
+ let(:property) { ComposedValidations::ValidatedProperty.new(:title, :title_ids) }
42
+ let(:asset) { double("Object", :title_ids => result) }
43
+ context "when validator returns false" do
44
+ let(:valid) { false }
45
+ it "should access one way and add a message for another property" do
46
+ expect(asset).to have_received(:title_ids)
47
+ expect(errors).to have_received(:add).with(:title, "is so awful")
48
+ end
49
+ end
50
+ end
51
+ context "when validator returns false" do
52
+ let(:valid) { false }
53
+ it "should add an error" do
54
+ expect(errors).to have_received(:add).with(property, "is so awful")
55
+ end
56
+ it "should return false" do
57
+ expect(valid_result).to eq false
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'active_model'
3
+
4
+ RSpec.describe "Or Validations Spec" do
5
+ before do
6
+ class MyObject
7
+ include ActiveModel::Model
8
+ attr_accessor :title, :description
9
+ end
10
+ class ValueIsFrank
11
+ def valid?(value)
12
+ value.to_s == "Frank"
13
+ end
14
+
15
+ def message
16
+ "needs to be equal to Frank"
17
+ end
18
+ end
19
+ class LengthIsFour
20
+ def valid?(value)
21
+ value.to_s.length == 4
22
+ end
23
+
24
+ def message
25
+ "needs to have a length of 4 characters"
26
+ end
27
+ end
28
+ end
29
+ after do
30
+ Object.send(:remove_const, :MyObject)
31
+ Object.send(:remove_const, :ValueIsFrank)
32
+ Object.send(:remove_const, :LengthIsFour)
33
+ end
34
+ let(:my_object) { MyObject.new }
35
+ let(:resource) do
36
+ ComposedValidations::DecorateProperties.new(
37
+ my_object,
38
+ validation_map
39
+ ).run
40
+ end
41
+ context "when using an OR validator" do
42
+ let(:validation_map) do
43
+ {
44
+ :title => [
45
+ ComposedValidations::OrValidator.new([
46
+ ValueIsFrank.new,
47
+ LengthIsFour.new
48
+ ])
49
+ ]
50
+ }
51
+ end
52
+ it "should fail if both are invalid" do
53
+ expect(resource).not_to be_valid
54
+ end
55
+ it "should succeed if one is valid" do
56
+ resource.title = "Frank"
57
+ expect(resource).to be_valid
58
+ end
59
+ it "should succeed if the other is valid" do
60
+ resource.title = "1234"
61
+ expect(resource).to be_valid
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'active_model'
3
+
4
+ RSpec.describe "Validations Integration Spec" do
5
+ before do
6
+ class MyObject
7
+ include ActiveModel::Model
8
+ attr_accessor :title, :description
9
+ end
10
+ class ValueIsFrank
11
+ def valid?(value)
12
+ value.to_s == "Frank"
13
+ end
14
+
15
+ def message
16
+ "needs to be equal to Frank"
17
+ end
18
+ end
19
+ class LengthIsFive
20
+ def valid?(value)
21
+ value.to_s.length == 5
22
+ end
23
+
24
+ def message
25
+ "needs to have a length of 5 characters"
26
+ end
27
+ end
28
+ end
29
+ after do
30
+ Object.send(:remove_const, :MyObject)
31
+ Object.send(:remove_const, :ValueIsFrank)
32
+ Object.send(:remove_const, :LengthIsFive)
33
+ end
34
+ let(:my_object) { MyObject.new }
35
+ let(:validation_map) do
36
+ { :title => ValueIsFrank.new }
37
+ end
38
+ let(:resource) do
39
+ ComposedValidations::DecorateProperties.new(
40
+ my_object,
41
+ validation_map
42
+ ).run
43
+ end
44
+ context "when validations are set" do
45
+ it "should use them" do
46
+ expect(resource).not_to be_valid
47
+ expect(resource.errors.messages).to eq ({:title => ["needs to be equal to Frank"]})
48
+ end
49
+ context "and there are multiple validations" do
50
+ let(:validation_map) do
51
+ {
52
+ :title => [
53
+ ValueIsFrank.new,
54
+ LengthIsFive.new
55
+ ]
56
+ }
57
+ end
58
+ it "should validate them both" do
59
+ expect(resource).not_to be_valid
60
+ expect(resource.errors.messages).to eq ({:title => [
61
+ "needs to be equal to Frank",
62
+ "needs to have a length of 5 characters"
63
+ ]})
64
+ end
65
+ it "should validate one if the other is valid" do
66
+ resource.title = "12345"
67
+ expect(resource).not_to be_valid
68
+ expect(resource.errors.messages).to eq ({:title => ["needs to be equal to Frank"]})
69
+ end
70
+ end
71
+ context "and the values are okay" do
72
+ let(:my_object) do
73
+ m = MyObject.new
74
+ m.title = "Frank"
75
+ m
76
+ end
77
+ it "should be valid" do
78
+ expect(resource).to be_valid
79
+ expect(resource.errors.messages).to be_empty
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,94 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ require 'composed_validations'
20
+ require 'pry'
21
+ require 'pry-byebug'
22
+ RSpec.configure do |config|
23
+ # rspec-expectations config goes here. You can use an alternate
24
+ # assertion/expectation library such as wrong or the stdlib/minitest
25
+ # assertions if you prefer.
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ # rspec-mocks config goes here. You can use an alternate test double
38
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
39
+ config.mock_with :rspec do |mocks|
40
+ # Prevents you from mocking or stubbing a method that does not exist on
41
+ # a real object. This is generally recommended, and will default to
42
+ # `true` in RSpec 4.
43
+ mocks.verify_partial_doubles = true
44
+ end
45
+
46
+ # The settings below are suggested to provide a good initial experience
47
+ # with RSpec, but feel free to customize to your heart's content.
48
+ =begin
49
+ # These two settings work together to allow you to limit a spec run
50
+ # to individual examples or groups you care about by tagging them with
51
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
52
+ # get run.
53
+ config.filter_run :focus
54
+ config.run_all_when_everything_filtered = true
55
+
56
+ # Limits the available syntax to the non-monkey patched syntax that is
57
+ # recommended. For more details, see:
58
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
59
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
60
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
61
+ config.disable_monkey_patching!
62
+
63
+ # This setting enables warnings. It's recommended, but in some cases may
64
+ # be too noisy due to issues in dependencies.
65
+ config.warnings = true
66
+
67
+ # Many RSpec users commonly either run the entire suite or an individual
68
+ # file, and it's useful to allow more verbose output when running an
69
+ # individual spec file.
70
+ if config.files_to_run.one?
71
+ # Use the documentation formatter for detailed output,
72
+ # unless a formatter has already been configured
73
+ # (e.g. via a command-line flag).
74
+ config.default_formatter = 'doc'
75
+ end
76
+
77
+ # Print the 10 slowest examples and example groups at the
78
+ # end of the spec run, to help surface which specs are running
79
+ # particularly slow.
80
+ config.profile_examples = 10
81
+
82
+ # Run specs in random order to surface order dependencies. If you find an
83
+ # order dependency and want to debug it, you can fix the order by providing
84
+ # the seed, which is printed after each run.
85
+ # --seed 1234
86
+ config.order = :random
87
+
88
+ # Seed global randomization in this process using the `--seed` CLI option.
89
+ # Setting this allows you to use `--seed` to deterministically reproduce
90
+ # test failures related to randomization by passing the same `--seed` value
91
+ # as the one that triggered the failure.
92
+ Kernel.srand config.seed
93
+ =end
94
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: composed_validations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Trey Terrell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: attr_extras
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '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.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.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: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
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
+ - !ruby/object:Gem::Dependency
98
+ name: activemodel
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description:
112
+ email:
113
+ - trey.terrell@oregonstate.edu
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - circle.yml
125
+ - composed_validations.gemspec
126
+ - lib/composed_validations.rb
127
+ - lib/composed_validations/decorate_properties.rb
128
+ - lib/composed_validations/or_string_joiner.rb
129
+ - lib/composed_validations/or_validator.rb
130
+ - lib/composed_validations/property_validator.rb
131
+ - lib/composed_validations/validated_property.rb
132
+ - lib/composed_validations/version.rb
133
+ - lib/composed_validations/with_validated_property.rb
134
+ - spec/composed_validations/decorate_properties_spec.rb
135
+ - spec/composed_validations/or_string_joiner_spec.rb
136
+ - spec/composed_validations/or_validator_spec.rb
137
+ - spec/composed_validations/validated_property_spec.rb
138
+ - spec/composed_validations/with_validated_property_spec.rb
139
+ - spec/integration/or_validation_spec.rb
140
+ - spec/integration/validation_spec.rb
141
+ - spec/spec_helper.rb
142
+ homepage: http://github.com/terrellt/composed_validations
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.4.5
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Composes validations onto properties of an object.
166
+ test_files:
167
+ - spec/composed_validations/decorate_properties_spec.rb
168
+ - spec/composed_validations/or_string_joiner_spec.rb
169
+ - spec/composed_validations/or_validator_spec.rb
170
+ - spec/composed_validations/validated_property_spec.rb
171
+ - spec/composed_validations/with_validated_property_spec.rb
172
+ - spec/integration/or_validation_spec.rb
173
+ - spec/integration/validation_spec.rb
174
+ - spec/spec_helper.rb
175
+ has_rdoc: