abort_if 0.1.0

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