composed_validations 0.0.1

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.
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: