bail 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.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .irbrc
19
+ Guardfile
20
+ .guardrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-p392@bail --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bail.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 bjh
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,87 @@
1
+ # Bail
2
+
3
+ #### What
4
+ A miniscule DSL to write guard clauses. Also to ask some basic questions of my types when I get curious.
5
+
6
+ #### Why
7
+ I was finding my methods were collecting a top layer of IF/ELSE statements that got harder to read and maintain.
8
+
9
+ #### How
10
+ Sweet sexy voodoo magic.
11
+
12
+ ***
13
+
14
+ A basic *un-sugared* guard looks something like this:
15
+ ```
16
+ Bail.when(:any, :of, :these, :things) {|item| item.nil?}
17
+ ```
18
+
19
+ So you pass in an enumerator (defaults are the Enumerable module methods), any number of arguments, and a `block` for the condition test.
20
+
21
+ Super *easy* and super *cheezy*.
22
+
23
+ There are more specialized versions that do not require a block:
24
+ These are really just lightly *sugared* wrappers around Enumerable methods...
25
+
26
+ ```
27
+ Bail.when_any(condition, *objects)
28
+ Bail.when_all(condition, *objects)
29
+ Bail.when_one(condition, *objects)
30
+ Bail.when_none(condition, *objects)
31
+ ```
32
+
33
+ #### Why would you care?
34
+ To understand the **why** of this gem you can ask yourself this question:
35
+ Do I prefer to read this:
36
+ ```
37
+ [:one, :of, :these, :things].any? {|x| nil?}
38
+ ```
39
+ or this:
40
+ ```
41
+ Bail.when_any(:nil, :one, :of, :these, :things)
42
+ ```
43
+
44
+ #### Example Usage
45
+
46
+ Bail will usually live at the top of your methods.
47
+
48
+ ```
49
+ # Assuming that Bail.raise_on_error = false
50
+ def some_method(that, takes, arguments)
51
+ return if Bail.when(:nil, that, takes, arguments)
52
+ return if Bail.when_none({:is_a, String}, that, takes, arguments)
53
+
54
+ # I will use it for type discovery instead of blindly asking it to quack
55
+ # i.e. I know I want the takes variable to be an Integer but I get it as a String sometimes...
56
+ if Bail.when_any({:is_a: String}, takes)
57
+ Logger.debug("you are passing in `takes` to `some_method` as a String from somewhere...")
58
+ takes = takes.to_i
59
+ end
60
+ end
61
+ ```
62
+
63
+ ## Installation
64
+
65
+ Add this line to your application's Gemfile:
66
+
67
+ gem 'bail'
68
+
69
+ And then execute:
70
+
71
+ $ bundle
72
+
73
+ Or install it yourself as:
74
+
75
+ $ gem install bail
76
+
77
+ ## Usage
78
+
79
+ TODO: Write usage instructions here
80
+
81
+ ## Contributing
82
+
83
+ 1. Fork it ( http://github.com/<my-github-username>/bail/fork )
84
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
85
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
86
+ 4. Push to the branch (`git push origin my-new-feature`)
87
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task default: :spec
8
+
9
+ desc 'load gem files into IRB'
10
+ task :console do
11
+ exec 'irb -Ilib -rbail'
12
+ # exec 'irb -I lib -r startingscript.rb'
13
+ end
data/bail.gemspec ADDED
@@ -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 'bail/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bail"
8
+ spec.version = Bail::VERSION
9
+ spec.authors = ["bjh"]
10
+ spec.email = ["bjh@fake.fake"]
11
+ spec.summary = %q{Bail out of functions early}
12
+ spec.description = %q{Bail out of functions early...}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "guard-rspec"
25
+ # spec.add_development_dependency "guard"
26
+ # spec.add_development_dependency "guard-shell"
27
+ # spec.add_development_dependency 'rb-fsevent', '~> 0.9'
28
+ end
@@ -0,0 +1,9 @@
1
+
2
+ module Bail
3
+ class Behavior
4
+ protected
5
+ def run(&block)
6
+ raise 'override me or you will be trampled by unicorns!'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'behavior.rb'
2
+
3
+ module Bail
4
+ class RaiseBehavior < Behavior
5
+ def run(&block)
6
+ yield block
7
+ rescue Bail::ConditionError => e
8
+ if not Bail.suppress_output
9
+ Bail.logger.warn(e.message)
10
+ end
11
+
12
+ raise e
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'behavior.rb'
2
+
3
+ module Bail
4
+ class ReturnBehavior < Behavior
5
+
6
+ attr_accessor :result
7
+
8
+ def run(&block)
9
+ yield block
10
+ result = false
11
+ rescue Bail::ConditionError => e
12
+ result = true
13
+
14
+ if not Bail.suppress_output
15
+ Bail.logger.warn(e.message)
16
+ end
17
+ ensure
18
+ return result
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'helpers.rb'
2
+
3
+ module Bail
4
+ class ConditionParser
5
+ attr_accessor :condition
6
+
7
+ def initialize(condition)
8
+ @condition = make_callable(condition)
9
+ end
10
+
11
+ def test(object)
12
+ condition.call(object)
13
+ end
14
+
15
+ protected
16
+ # TODO: find out if Helpers is actually included as protected
17
+ include Helpers
18
+
19
+ def make_callable(condition)
20
+ if condition.respond_to? :call
21
+ condition
22
+ elsif condition.is_a? Hash
23
+ condition_hash_to_lambda(condition)
24
+ else
25
+ # Assume Symbol or String for now
26
+ # so wrap it in a pretty dress
27
+ question = questionable(condition)
28
+ ->(to) { to.send(question) }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'helpers.rb'
2
+
3
+ module Bail
4
+ class ConditionTester
5
+ include Helpers
6
+
7
+ attr_accessor :type
8
+
9
+ def initialize(type)
10
+ # can be methods from Enumerable basically
11
+ # i.e. :any?, :all?
12
+ @type = questionable(type)
13
+ end
14
+
15
+ def run(condition_parser, objects)
16
+ if objects.send(type) {|object| condition_parser.test(object)}
17
+ raise Bail::ConditionError.new('A Bail condition has failed.')
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Bail
2
+ module Configuration
3
+ attr_accessor :logger
4
+ attr_accessor :suppress_output
5
+ attr_accessor :behavior
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Bail
3
+ module Helpers
4
+ def questionable(condition)
5
+ # TODO: Object.new.extend(Enumerable).respond_to? condition
6
+ # WHY: to allow {is_a: Thing} which becomes - [...].is_a? Thing
7
+ condition.to_s.gsub(/\?$/, '').gsub(/$/, '?').to_sym
8
+ end
9
+
10
+ def condition_hash_to_lambda(condition)
11
+ test = questionable(condition.keys.first)
12
+ against = condition.values.first
13
+
14
+ ->(testee) { testee.send(test, against) }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Bail
2
+ VERSION = "0.0.1"
3
+ end
data/lib/bail.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'logger'
2
+ require 'bail/version'
3
+ require 'bail/configuration'
4
+ require 'bail/condition_parser.rb'
5
+ require 'bail/condition_tester.rb'
6
+ require 'bail/behavior/raise_behavior.rb'
7
+ require 'bail/behavior/return_behavior.rb'
8
+
9
+ module Bail
10
+ class ConditionError < ArgumentError; end
11
+
12
+ # Bail.when(:any, :of, :these, :things) {|item| item.nil?}
13
+ def self.when(enumerator, *objects, &block)
14
+ execute(enumerator, block, objects)
15
+ end
16
+
17
+ def self.when_any(condition, *objects)
18
+ execute(:any?, condition, objects)
19
+ end
20
+
21
+ def self.when_all(condition, *objects)
22
+ execute(:all?, condition, objects)
23
+ end
24
+
25
+ def self.when_one(condition, *objects)
26
+ execute(:one?, condition, objects)
27
+ end
28
+
29
+ def self.when_none(condition, *objects)
30
+ execute(:none?, condition, objects)
31
+ end
32
+
33
+ def self.execute(type, condition, objects)
34
+ Bail.behavior.run do
35
+ ConditionTester.new(type).run(ConditionParser.new(condition), objects)
36
+ end
37
+ end
38
+
39
+ private_class_method :execute
40
+
41
+ extend Configuration
42
+
43
+ # where the wood goes
44
+ Bail.logger = Logger.new(STDOUT)
45
+ Bail.logger.level = Logger::DEBUG
46
+ Bail.logger.formatter = proc do |severity, datetime, progname, msg|
47
+ "Bail::[#{msg}]\n"
48
+ end
49
+
50
+ # handle the behavior preferences
51
+ def self.raise_on_error
52
+ @@raise_on_error
53
+ end
54
+
55
+ def self.raise_on_error=(boolean_value)
56
+ @@raise_on_error = boolean_value
57
+
58
+ if boolean_value
59
+ Bail.behavior = RaiseBehavior.new
60
+ else
61
+ Bail.behavior = ReturnBehavior.new
62
+ end
63
+ end
64
+
65
+ # default to return true/false
66
+ Bail.raise_on_error = true
67
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'bail/helpers.rb'
3
+
4
+ describe Bail::Helpers do
5
+ subject { Object.new.extend(Bail::Helpers) }
6
+
7
+ describe '.questionable' do
8
+ context 'when the condition already has a `?` on the end' do
9
+ it 'returns the condition unchanged' do
10
+ expect(subject.questionable(:is_a?)).to eq :is_a?
11
+ end
12
+ end
13
+
14
+ context 'when the condition does not have a `?` on the end' do
15
+ it 'returns the condition with a ? on the end' do
16
+ expect(subject.questionable(:is_a)).to eq :is_a?
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '.condition_hash_to_lambda' do
22
+ it 'returns a lambda' do
23
+ f = subject.condition_hash_to_lambda(is_a: String)
24
+ expect(f).to be_a Proc
25
+ end
26
+ end
27
+ end
data/spec/bail_spec.rb ADDED
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+ require 'bail.rb'
3
+
4
+ describe Bail do
5
+ before :each do
6
+ Bail.suppress_output = true
7
+ Bail.raise_on_error = false
8
+ end
9
+
10
+ after :each do
11
+ Bail.suppress_output = false
12
+ Bail.raise_on_error = true
13
+ end
14
+
15
+ describe '.behavior' do
16
+ context 'raise_on_error' do
17
+ it 'should raise an error when true' do
18
+ Bail.raise_on_error = true
19
+
20
+ expect {
21
+ Bail.when_any(:nil, nil)
22
+ }.to raise_error
23
+ end
24
+
25
+ it 'should return a boolean result when false' do
26
+ Bail.raise_on_error = false
27
+
28
+ expect {
29
+ Bail.when_any(:nil, nil)
30
+ }.not_to raise_error
31
+
32
+ expect(Bail.when_any(:nil, nil)).to be_true
33
+ end
34
+ end
35
+ end
36
+
37
+ describe '.when' do
38
+ it 'allows passing in a block as the condition test' do
39
+ r = Bail.when(:none, 1, 2, 3) { |x| x.nil? }
40
+ expect(r).to be_true
41
+ end
42
+ end
43
+
44
+ describe '.when_any' do
45
+ context 'using a lambda as the condition' do
46
+ it 'raises an error when any item is true' do
47
+ Bail.raise_on_error = true
48
+
49
+ expect {
50
+ Bail.when_any(->(x){x.nil?}, 1, nil, 3)
51
+ }.to raise_error
52
+ end
53
+ end
54
+
55
+ context 'using a symbol as the condition' do
56
+ it 'raises an error when any item is true' do
57
+ Bail.raise_on_error = true
58
+
59
+ expect {
60
+ Bail.when_any(:nil?, 1, 2, nil)
61
+ }.to raise_error
62
+ end
63
+
64
+ it 'does not raise an error when all items are false' do
65
+ expect {
66
+ Bail.when_any(:nil?, 1, 2, 3)
67
+ }.not_to raise_error
68
+ end
69
+ end
70
+
71
+ context 'using a Hash as the condition' do
72
+ it 'allows passing a type constraint along with the condition test' do
73
+ r = Bail.when_any({is_a: String}, 1, 2, '3')
74
+ expect(r).to be_true
75
+ end
76
+ end
77
+ end
78
+
79
+ describe '.when_all' do
80
+ it 'returns true when all items pass the condition test' do
81
+ r = Bail.when_all(:nil?, nil, nil, nil)
82
+ expect(r).to be_true
83
+ end
84
+
85
+ it 'returns false if any item fails the condition test' do
86
+ r = Bail.when_all(:nil?, nil, nil, 3)
87
+ expect(r).to be_false
88
+ end
89
+ end
90
+
91
+ describe '.when_one' do
92
+ it 'returns true if exactly one item is true' do
93
+ expect(Bail.when_one(:nil?, 1, 2, nil, 4, 5)).to be_true
94
+ end
95
+
96
+ it 'returns false if more than one item is true' do
97
+ expect(Bail.when_one(:nil?, 1, 2, nil, 4, 5, nil)).to be_false
98
+ end
99
+ end
100
+
101
+ describe '.when_none' do
102
+ it 'returns true if all items FAIL the test' do
103
+ expect(Bail.when_none(:nil?, 1, 2, 4, 5)).to be_true
104
+ end
105
+
106
+ it 'returns true if one or more items PASS the test' do
107
+ expect(Bail.when_none(:nil?, 1, 2, nil, 4, 5)).to be_false
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,15 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+
10
+ # Run specs in random order to surface order dependencies. If you find an
11
+ # order dependency and want to debug it, you can fix the order by providing
12
+ # the seed, which is printed after each run.
13
+ # --seed 1234
14
+ config.order = 'random'
15
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - bjh
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.5'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Bail out of functions early...
79
+ email:
80
+ - bjh@fake.fake
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .rspec
87
+ - .rvmrc
88
+ - Gemfile
89
+ - LICENSE.txt
90
+ - README.md
91
+ - Rakefile
92
+ - bail.gemspec
93
+ - lib/bail.rb
94
+ - lib/bail/behavior/behavior.rb
95
+ - lib/bail/behavior/raise_behavior.rb
96
+ - lib/bail/behavior/return_behavior.rb
97
+ - lib/bail/condition_parser.rb
98
+ - lib/bail/condition_tester.rb
99
+ - lib/bail/configuration.rb
100
+ - lib/bail/helpers.rb
101
+ - lib/bail/version.rb
102
+ - spec/bail/helpers_spec.rb
103
+ - spec/bail_spec.rb
104
+ - spec/spec_helper.rb
105
+ homepage: ''
106
+ licenses:
107
+ - MIT
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.23
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Bail out of functions early
130
+ test_files:
131
+ - spec/bail/helpers_spec.rb
132
+ - spec/bail_spec.rb
133
+ - spec/spec_helper.rb