abort_if 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in abort_if.gemspec
4
+ gemspec
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.("routing/#{m[1]}_routing"),
51
+ rspec.spec.("controllers/#{m[1]}_controller"),
52
+ rspec.spec.("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
@@ -0,0 +1,74 @@
1
+ # AbortIf
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/AbortIf.svg)](http://badge.fury.io/rb/AbortIf) [![Build Status](https://travis-ci.org/mooreryan/abort_if.svg?branch=master)](https://travis-ci.org/mooreryan/abort_if) [![Coverage Status](https://coveralls.io/repos/github/mooreryan/abort_if/badge.svg?branch=master)](https://coveralls.io/github/mooreryan/abort_if?branch=master)
4
+
5
+ Simple error logging and assertions for Ruby.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'abort_if'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install abort_if
22
+
23
+ ## Usage
24
+
25
+ See [documentation](http://www.rubydoc.info/gems/AbortIf) for complete
26
+ usage.
27
+
28
+ ### Example ###
29
+
30
+ Here is a tiny example program.
31
+
32
+ require "abort_if"
33
+
34
+ include AbortIf
35
+ include AbortIf::Assert
36
+
37
+ a = 5
38
+ b = 5
39
+ numbers = [1, 2, 3]
40
+ fname = "apple_pie.txt"
41
+ hash = nil
42
+
43
+ # this will pass
44
+ assert a == b, "%d should equal %d", a, b
45
+
46
+ # this will pass
47
+ abort_unless numbers.include?(1), "numbers should include 1"
48
+
49
+ # this will pass
50
+ abort_if_file_exists fname, "#{fname} should not exist"
51
+
52
+ File.open(fname, "w") do |f|
53
+ f.puts "Important info to follow...."
54
+ end
55
+
56
+ # oops, this will abort the progam and will log a nice message
57
+ # like this
58
+ # F, [2016-03-06T18:14:03.255900 #5357] FATAL -- : the hash was nil
59
+ abort_unless hash, "the hash was nil"
60
+
61
+ ## Development
62
+
63
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
64
+
65
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
66
+
67
+ ## Contributing
68
+
69
+ Bug reports and pull requests are welcome on GitHub at
70
+ https://github.com/mooreryan/abort_if. This project is intended to be
71
+ a safe, welcoming space for collaboration, and contributors are
72
+ expected to adhere to the
73
+ [Contributor Covenant](http://contributor-covenant.org) code of
74
+ conduct.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'abort_if/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "abort_if"
8
+ spec.version = AbortIf::VERSION
9
+ spec.authors = ["Ryan Moore"]
10
+ spec.email = ["moorer@udel.edu"]
11
+
12
+ spec.summary = %q{Easy error logging and assertions.}
13
+ spec.description = %q{Easy error logging and assertions..}
14
+ spec.homepage = "https://github.com/mooreryan/abort_if"
15
+ spec.license = "GPLv3: http://www.gnu.org/licenses/gpl.txt"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.required_ruby_version = ">= 1.9.3"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.11"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "guard-rspec", "~> 4.6", ">= 4.6.4"
28
+ spec.add_development_dependency "yard", "~> 0.8.7.6"
29
+ spec.add_development_dependency "coveralls", "~> 0.8.11"
30
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "abort_if"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,127 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of AbortIf.
5
+ #
6
+ # AbortIf is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # AbortIf is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with AbortIf. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require "abort_if/version"
20
+ require "abort_if/error"
21
+ require "abort_if/argument_error"
22
+ require "assert/assert"
23
+ require "logger"
24
+
25
+ module AbortIf
26
+ # Writes a message to the logger then calls abort if test is truthy,
27
+ # else returns nil.
28
+ #
29
+ # If test is true, write contents of msg to an error logger, then
30
+ # abort.
31
+ #
32
+ # @example When test is true
33
+ # arr = []
34
+ # abort_if arr.empty?, "Array empty"
35
+ # # Prints this message to standard error, then exits
36
+ # F, [2016-03-06T18:14:03.255900 #5357] FATAL -- : Array empty
37
+ #
38
+ # @example When test is false
39
+ # arr = [1,2,3]
40
+ # abort_if arr.empty?, "Array empty"
41
+ # #=> nil
42
+ #
43
+ # @param test Some object or test
44
+ # @param msg [String] the message written by the
45
+ # error logger
46
+ #
47
+ # @raise [SystemExit] if test is truthy
48
+ #
49
+ # @return [nil] if test is false or nil
50
+ #
51
+ # @note The abort_if style methods don't interpolate arguments to
52
+ # msg as the Assert module methods do
53
+ def abort_if test, msg="Fatal error"
54
+ if test
55
+ logger.fatal msg
56
+ abort
57
+ end
58
+ end
59
+
60
+ # Writes a message to the logger then aborts if fname is a file that
61
+ # already exists.
62
+ #
63
+ # @param fname [String] name of a file
64
+ #
65
+ # @raise [SystemExit] if file exists
66
+ #
67
+ # @return [nil] if file does not exist
68
+ def abort_if_file_exists fname
69
+ abort_if File.exists?(fname),
70
+ "File '#{fname}' already exists"
71
+ end
72
+
73
+ # Writes a message to the logger then calls abort if test is false
74
+ # or nil, else returns nil.
75
+ #
76
+ # @example When test is true
77
+ # arr = []
78
+ # abort_unless arr.empty?, "Array should be empty"
79
+ # #=> nil
80
+ #
81
+ # @example When test is false
82
+ # arr = [1,2,3]
83
+ # abort_unless arr.empty?, "Array not empty"
84
+ # # Prints this message to standard error, then exits
85
+ # F, [2016-03-06T18:14:03.255900 #5357] FATAL -- : Array not empty
86
+ #
87
+ # @param (see #abort_if)
88
+ #
89
+ # @raise [SystemExit] if test is false or nil
90
+ #
91
+ # @return [nil] if test is truthy
92
+ def abort_unless test, msg="Fatal error"
93
+ abort_if !test, msg
94
+ end
95
+
96
+ # Writes a message to the logger then aborts if fname is a file that
97
+ # does not exist.
98
+ #
99
+ # @param (see #abort_if_file_exists)
100
+ #
101
+ # @raise [SystemExit] if file does not exist
102
+ #
103
+ # @return [nil] if file exists
104
+ def abort_unless_file_exists fname
105
+ abort_unless File.exists?(fname),
106
+ "File '#{fname}' does not exist"
107
+ end
108
+
109
+ # Returns a Logger.
110
+ #
111
+ # This method will create an instance of Logger with all the default
112
+ # options if one does not already exist. If a logger has already
113
+ # been created, return the old one.
114
+ #
115
+ # @example Logging an error
116
+ # logger.error "An error occured"
117
+ #
118
+ # @return [Logger] a module level instance of Logger
119
+ #
120
+ # @note There is only one logger for the module.
121
+ # @note You can modify this logger just any of the Logger class from
122
+ # the Ruby standard library (see
123
+ # http://ruby-doc.org/stdlib-2.2.0/libdoc/logger/rdoc/Logger.html)
124
+ def logger
125
+ @@logger ||= Logger.new STDERR
126
+ end
127
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of AbortIf.
5
+ #
6
+ # AbortIf is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # AbortIf is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with AbortIf. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module AbortIf
20
+ # Raised if a method is passed improper arguments.
21
+ class ArgumentError < Error
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of AbortIf.
5
+ #
6
+ # AbortIf is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # AbortIf is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with AbortIf. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module AbortIf
20
+ # Basic Error from which all other AbortIf errors inherit from.
21
+ #
22
+ # To rescue any error raised specifically by the AbortIf module, you
23
+ # could do `resuce AbortIf::Error => e`
24
+ class Error < StandardError
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of AbortIf.
5
+ #
6
+ # AbortIf is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # AbortIf is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with AbortIf. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module AbortIf
20
+ VERSION = "0.1.0"
21
+ end
@@ -0,0 +1,216 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of AbortIf.
5
+ #
6
+ # AbortIf is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # AbortIf is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with AbortIf. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module AbortIf
20
+ module Assert
21
+ # Error raised when any assert or refute method fails
22
+ class AssertionFailureError < Error
23
+ end
24
+
25
+ # If test is true, return nil, else raise AssertionFailureError
26
+ # with the given message.
27
+ #
28
+ # @example Test is true
29
+ # a, b = 1, 1
30
+ # assert a == b, "%d should equal %d", a, b
31
+ # #=> nil
32
+ #
33
+ # @example Test is false
34
+ # arr = [1,2,3]
35
+ # assert arr.empty?,
36
+ # "Array should be empty, had %d items"
37
+ # arr.count
38
+ # # raises AssertionFailureError with given msg
39
+ #
40
+ # @param test Some object or test
41
+ # @param msg [String] the message passed to the
42
+ # AssertionFailureError
43
+ # @param *args arguments to interpolate into msg
44
+ #
45
+ # @raise [AssertionFailureError] if test is false or nil
46
+ #
47
+ # @return [nil] if test is truthy
48
+ def assert test, msg="Assertion failed", *args
49
+ unless test
50
+ raise AssertionFailureError, msg % args
51
+ end
52
+ end
53
+
54
+ # If test is false or nil, return nil, else raise
55
+ # AssertionFailureError.
56
+ #
57
+ # @param (see #assert)
58
+ #
59
+ # @raise [AssertionFailureError] if test is truthy
60
+ #
61
+ # @return [nil] if thest is false or nil
62
+ #
63
+ # @note The opposite of assert
64
+ def refute test, msg="Assertion failed", *args
65
+ assert !test, msg, *args
66
+ end
67
+
68
+ # If coll includes obj, return nil, else raise
69
+ # AssertionFailureError.
70
+ #
71
+ # @example Passing
72
+ # assert_includes [1,2,3], 1
73
+ # #=> nil
74
+ #
75
+ # @example Failing
76
+ # assert_includes [1,2,3], 10
77
+ # # raises AssertionFailureError
78
+ #
79
+ # @param coll [#include?] some collection
80
+ # @param obj the object to check for
81
+ #
82
+ # @raise [AssertionFailureError] if coll does not include object
83
+ # @raise [ArgumentError] if coll does not respond to :include?
84
+ #
85
+ # @return [nil] if coll includes obj
86
+ def assert_includes coll, obj
87
+ check_responds_to coll, :include?
88
+
89
+ assert coll.include?(obj),
90
+ "Expected coll to include obj"
91
+ end
92
+
93
+ # If coll includes obj, raise AssertionFailureError, else return
94
+ # nil.
95
+ #
96
+ # @param (see #assert_includes)
97
+ #
98
+ # @raise [AssertionFailureError] if coll does include object
99
+ # @raise [ArgumentError] if coll doesn't respond to :include?
100
+ #
101
+ # @return [nil] if coll does not include obj
102
+ def refute_includes coll, obj
103
+ check_responds_to coll, :include?
104
+
105
+ refute coll.include?(obj),
106
+ "Expected coll not to include obj"
107
+ end
108
+
109
+ # If any key is not present in coll, raise AssertionFailureError,
110
+ # else return nil.
111
+ #
112
+ # @example Passing
113
+ # assert_keys {a: 2, b: 1}, :a, :b
114
+ # #=> nil
115
+ #
116
+ # @example Failing
117
+ # assert_keys {a: 2, b: 1}, :a, :b, :c
118
+ # # raises AssertionFailureError
119
+ #
120
+ # @param coll [#[]] collection of things
121
+ # @param *keys keys to check for
122
+ #
123
+ # @raise [AssertionFailureError] if coll does include every key
124
+ # @raise [ArgumentError] if coll doesn't respond to :[]
125
+ #
126
+ # @return [nil] if coll has every key
127
+ def assert_keys coll, *keys
128
+ check_responds_to coll, :[]
129
+
130
+ check_not_empty keys
131
+
132
+ assert keys.all? { |key| coll[key] },
133
+ "Expected coll to include all keys"
134
+ end
135
+
136
+ # If the key is present in hash, return nil, else raise
137
+ # AssertionFailureError.
138
+ #
139
+ # @example Passing
140
+ # assert_has_key {a: 2, b: 1}, :a
141
+ # #=> nil
142
+ #
143
+ # @example Failing
144
+ # assert_has_key {a: 2, b: 1}, :c
145
+ # # raises AssertionFailureError
146
+ #
147
+ # @param hash [#has_key?] anything that responds to :has_key?
148
+ # @param key the key to check for
149
+ #
150
+ # @raise [AssertionFailureError] if hash doesn't include key
151
+ # @raise [ArgumentError] if coll doesn't respond to :has_key?
152
+ #
153
+ # @return [nil] if hash has key
154
+ def assert_has_key hash, key
155
+ check_responds_to hash, :has_key?
156
+
157
+ assert hash.has_key?(key),
158
+ "Expected hash to include key"
159
+ end
160
+
161
+ # If the key is present in hash, raise AssertionFailureError, else
162
+ # return nil.
163
+ #
164
+ # @example Passing
165
+ # refute_has_key {a: 2, b: 1}, :a
166
+ # # raises AssertionFailureError
167
+ #
168
+ # @example Failing
169
+ # refute_has_key {a: 2, b: 1}, :c
170
+ # #=> nil
171
+ #
172
+ # @param (see #assert_has_key)
173
+ #
174
+ # @raise [AssertionFailureError] if hash includes key
175
+ # @raise [ArgumentError] if coll doesn't respond to :has_key?
176
+ #
177
+ # @return [nil] if hash does not have key
178
+ def refute_has_key hash, key
179
+ check_responds_to hash, :has_key?
180
+
181
+ refute hash.has_key?(key),
182
+ "Expected hash not to include key"
183
+ end
184
+
185
+ # If coll is given length, return nil, else raise
186
+ # AssertionFailureError.
187
+ #
188
+ # @param coll [#length] anything that responds to :length
189
+ # @param len [Number] the length to check for
190
+ #
191
+ # @raise [AssertionFailureError] if length of coll doesn't match
192
+ # given len
193
+ # @raise [ArgumentError] if coll doesn't respond to :length
194
+ #
195
+ # @return [nil] if length of coll matches given len
196
+ def assert_length coll, len
197
+ check_responds_to coll, :length
198
+
199
+ assert coll.length == len,
200
+ "Expected coll to have %d items",
201
+ len
202
+ end
203
+
204
+ private
205
+
206
+ def check_responds_to coll, method
207
+ raise ArgumentError unless coll.respond_to? method
208
+ end
209
+
210
+ def check_not_empty coll
211
+ check_responds_to coll, :count
212
+
213
+ raise ArgumentError unless coll.count > 0
214
+ end
215
+ end
216
+ end