warnings 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/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.*
3
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "Warnings Documentation" --protected
data/ChangeLog.md ADDED
@@ -0,0 +1,11 @@
1
+ ### 0.1.0 / 2011-06-24
2
+
3
+ * Initial release:
4
+ * Respects `$VERBOSE` (`ruby -w`) and `$DEBUG` (`ruby -d`)
5
+ * Search Warning Messages by:
6
+ * Message
7
+ * Source File
8
+ * Source Method
9
+ * Prints unique Warning messages upon exit.
10
+ * ANSI Coloring.
11
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Hal Brodigan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # warnings
2
+
3
+ * [Source](http://github.com/postmodern/warnings)
4
+ * [Issues](http://github.com/postmodern/warnings/issues)
5
+ * [Documentation](http://rubydoc.info/gems/warnings/frames)
6
+ * [Email](mailto:postmodern.mod3 at gmail.com)
7
+
8
+ ## Description
9
+
10
+ Warnings provides a searchable and more readable Warning Message
11
+ facility for Ruby. With Warnings, one can save all warning messages
12
+ generated by your code, search through them and print them upon exit.
13
+
14
+ ## Features
15
+
16
+ * Respects `$VERBOSE` (`ruby -w`) and `$DEBUG` (`ruby -d`)
17
+ * Search Warning Messages by:
18
+ * Message
19
+ * Source File
20
+ * Source Method
21
+ * Prints unique Warning messages upon exit.
22
+ * ANSI Coloring.
23
+
24
+ ## Examples
25
+
26
+ require 'warnings'
27
+
28
+ def danger!
29
+ warn "Fire in the disco!"
30
+ end
31
+
32
+ danger!
33
+ danger!
34
+
35
+ Warnings.grep(/fire/)
36
+ # => [...]
37
+
38
+ Warnings.from('foo/bar.rb')
39
+ # => [...]
40
+
41
+ Warnings.from_method('danger!')
42
+ # => [...]
43
+
44
+ exit
45
+ #
46
+ # Warnings:
47
+ #
48
+ # fire in the disco!
49
+ # lib/foo/bar.rb:42
50
+
51
+ ## Install
52
+
53
+ $ gem install warnings
54
+
55
+ ## Copyright
56
+
57
+ Copyright (c) 2011 Hal Brodigan
58
+
59
+ See {file:LICENSE.txt} for details.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ gem 'ore-tasks', '~> 0.4'
8
+ require 'ore/tasks'
9
+
10
+ Ore::Tasks.new
11
+ rescue LoadError => e
12
+ STDERR.puts e.message
13
+ STDERR.puts "Run `gem install ore-tasks` to install 'ore/tasks'."
14
+ end
15
+
16
+ begin
17
+ gem 'rspec', '~> 2.4'
18
+ require 'rspec/core/rake_task'
19
+
20
+ RSpec::Core::RakeTask.new
21
+ rescue LoadError => e
22
+ task :spec do
23
+ abort "Please run `gem install rspec` to install RSpec."
24
+ end
25
+ end
26
+
27
+ task :test => :spec
28
+ task :default => :spec
29
+
30
+ begin
31
+ gem 'yard', '~> 0.7.0'
32
+ require 'yard'
33
+
34
+ YARD::Rake::YardocTask.new
35
+ rescue LoadError => e
36
+ task :yard do
37
+ abort "Please run `gem install yard` to install YARD."
38
+ end
39
+ end
40
+ task :doc => :yard
data/gemspec.yml ADDED
@@ -0,0 +1,16 @@
1
+ name: warnings
2
+ summary: Provides a better Warning Message facility for Ruby.
3
+ description:
4
+ Warnings provides a searchable and more readable Warning Message
5
+ facility for Ruby. With Warnings, one can save all warning messages
6
+ generated by your code, search through them and print them upon exit.
7
+
8
+ license: MIT
9
+ authors: Postmodern
10
+ email: postmodern.mod3@gmail.com
11
+ homepage: http://github.com/postmodern/warnings
12
+
13
+ development_dependencies:
14
+ ore-tasks: ~> 0.4
15
+ rspec: ~> 2.4
16
+ yard: ~> 0.7.0
data/lib/warnings.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'warnings/version'
2
+ require 'warnings/warnings'
3
+ require 'warnings/mixin'
4
+
5
+ include Warnings::Mixin
6
+
7
+ at_exit do
8
+ if (!$WARNINGS.empty? && ($VERBOSE || $DEBUG))
9
+ $stderr.puts
10
+ $stderr.puts "Warnings:"
11
+ $stderr.puts
12
+
13
+ unique_warnings = {}
14
+
15
+ $WARNINGS.each do |warning|
16
+ unique_warnings[warning.source_location] ||= warning
17
+ end
18
+
19
+ unique_warnings.each_value { |warning| warning.print }
20
+
21
+ $stderr.puts
22
+ end
23
+ end
@@ -0,0 +1,54 @@
1
+ require 'warnings/warning'
2
+ require 'warnings/warnings'
3
+
4
+ module Warnings
5
+ module Mixin
6
+ #
7
+ # Enables or disables warnings.
8
+ #
9
+ # @param [Boolean] mode
10
+ # Specifies whether warnings will be enabled or disabled.
11
+ #
12
+ # @return [Boolean]
13
+ # Specifies whether warnings are enabled.
14
+ #
15
+ def warnings=(mode)
16
+ @warnings = mode
17
+ end
18
+
19
+ #
20
+ # Determines whether warnings are enabled.
21
+ #
22
+ # @return [Boolean]
23
+ # Specifies whether warnings are enabled.
24
+ #
25
+ # @note
26
+ # Enabling `$VERBOSE` (`ruby -w`) or `$DEBUG` (`ruby -d`) will
27
+ # enable all warnings by default.
28
+ #
29
+ def warnings?
30
+ ($VERBOSE || $DEBUG) || (@warnings != false)
31
+ end
32
+
33
+ #
34
+ # Registers a warning.
35
+ #
36
+ # @param [String] message
37
+ # The warning message.
38
+ #
39
+ # @example
40
+ # warn "Foo#bar method will be removed in 1.0.0"
41
+ #
42
+ # @return [nil]
43
+ #
44
+ def warn(message)
45
+ if warnings?
46
+ super(message) if $DEBUG
47
+
48
+ $WARNINGS << Warning.new(message,caller)
49
+ end
50
+
51
+ return nil
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,4 @@
1
+ module Warnings
2
+ # warnings version
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,165 @@
1
+ module Warnings
2
+ class Warning
3
+
4
+ # The warning message
5
+ attr_reader :message
6
+
7
+ # The backtrace to the warning
8
+ #
9
+ # @return [Array<String>]
10
+ # The raw backtrace.
11
+ #
12
+ attr_reader :backtrace
13
+
14
+ # The source location of the warning.
15
+ #
16
+ # @return [Array<path, line>]
17
+ # The path and line number where the warning originated.
18
+ #
19
+ attr_reader :source_location
20
+
21
+ # The source method of the warning.
22
+ #
23
+ # @return [Symbol]
24
+ # The method name.
25
+ #
26
+ attr_reader :source_method
27
+
28
+ #
29
+ # Creates a new warning.
30
+ #
31
+ # @param [String] message
32
+ # The warning message.
33
+ #
34
+ # @param [Array<String>] backtrace
35
+ # The backtrace of the warning.
36
+ #
37
+ def initialize(message,backtrace)
38
+ @message = message
39
+ @backtrace = backtrace
40
+
41
+ file, line, context = @backtrace.first.split(':',3)
42
+
43
+ @source_location = [file, line.to_i]
44
+ @source_method = context[5..-2] if context
45
+ end
46
+
47
+ #
48
+ # The source file of the warning.
49
+ #
50
+ # @return [String]
51
+ # The path of the file.
52
+ #
53
+ def source_file
54
+ @source_location[0]
55
+ end
56
+
57
+ #
58
+ # The source line of the warning.
59
+ #
60
+ # @return [Integer]
61
+ # The line-number of the warning.
62
+ #
63
+ def source_line
64
+ @source_location[1]
65
+ end
66
+
67
+ #
68
+ # Compares the warning message to a pattern.
69
+ #
70
+ # @param [Regexp] pattern
71
+ # The pattern to match against.
72
+ #
73
+ # @return [Integer, nil]
74
+ # The index of the pattern match within the warning message.
75
+ #
76
+ def =~(pattern)
77
+ @message =~ message
78
+ end
79
+
80
+ #
81
+ # Compares the warning to another warning.
82
+ #
83
+ # @param [Warning] other
84
+ # The other warning to compare against.
85
+ #
86
+ # @return [Boolean]
87
+ # Specifies whether the two warnings represent the same message.
88
+ #
89
+ def ==(other)
90
+ (@message == other.message) &&
91
+ (@source_location == other.source_location) &&
92
+ (@source_method == other.source_method)
93
+ end
94
+
95
+ #
96
+ # Compares the warning to another warning.
97
+ #
98
+ # @param [Warning] other
99
+ # The other warning to compare against.
100
+ #
101
+ # @return [Boolean]
102
+ # Specifies whether the two warnings represent the same message.
103
+ #
104
+ def ===(other)
105
+ case other
106
+ when Warning
107
+ self == other
108
+ when Regexp, String
109
+ !(@message.match(other).nil?)
110
+ else
111
+ false
112
+ end
113
+ end
114
+
115
+ #
116
+ # Converts the warning to a String.
117
+ #
118
+ # @return [String]
119
+ # The warning message.
120
+ #
121
+ def to_s
122
+ @message.to_s
123
+ end
124
+
125
+ #
126
+ # Formats a warning.
127
+ #
128
+ # @return [String]
129
+ # The printable warning.
130
+ #
131
+ # @note
132
+ # Will include ANSI color codes, only if `STDOUT` is a TTY Terminal.
133
+ #
134
+ def print
135
+ trace = unless $DEBUG
136
+ @backtrace[0,5]
137
+ else
138
+ @backtrace
139
+ end
140
+
141
+ if $stderr.tty?
142
+ $stderr.puts " \e[33m#{@message}:\e[0m"
143
+ trace.each { |line| $stderr.puts "\t\e[2m#{line}\e[0m" }
144
+ else
145
+ $stderr.puts " #{@message}:"
146
+ trace.each { |line| $stderr.puts "\t#{line}" }
147
+ end
148
+ end
149
+
150
+ #
151
+ # Inspects the warning.
152
+ #
153
+ # @return [String]
154
+ # The inspected {#source_file}, {#source_line} and {#message}.
155
+ #
156
+ def inspect
157
+ if @source_method
158
+ "#{source_file}:#{source_line} (#{@source_method}): #{@message}"
159
+ else
160
+ "#{source_file}:#{source_line}: #{@message}"
161
+ end
162
+ end
163
+
164
+ end
165
+ end
@@ -0,0 +1,50 @@
1
+ module Warnings
2
+ # The global list of warnings
3
+ $WARNINGS ||= []
4
+
5
+ #
6
+ # Selects all warnings with a similar message.
7
+ #
8
+ # @param [String, Regexp] pattern
9
+ # The message pattern to search for.
10
+ #
11
+ # @return [Warning]
12
+ # The warnings from the sub-path.
13
+ #
14
+ def self.grep(pattern)
15
+ $WARNINGS.select { |warning| warning.message.match(pattern) }
16
+ end
17
+
18
+ #
19
+ # Selects all warnings originating from a file.
20
+ #
21
+ # @param [String] path
22
+ # The sub-path to search for.
23
+ #
24
+ # @return [Warning]
25
+ # The warnings from the sub-path.
26
+ #
27
+ def self.from(path)
28
+ $WARNINGS.select { |warning| warning.source_file.include?(path) }
29
+ end
30
+
31
+ #
32
+ # Selects all warnings originating from a method.
33
+ #
34
+ # @param [Regexp, String] name
35
+ # The method name or pattern to search for.
36
+ #
37
+ # @return [Warning]
38
+ # The warnings from the specified method.
39
+ #
40
+ def self.from_method(name)
41
+ selector = case name
42
+ when Regexp
43
+ lambda { |warning| warning.source_method =~ name }
44
+ else
45
+ lambda { |warning| warning.source_method == name }
46
+ end
47
+
48
+ $WARNINGS.select(&selector)
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'warnings/mixin'
3
+
4
+ describe Warnings::Mixin do
5
+ subject { Object.new.extend(Warnings::Mixin) }
6
+
7
+ it "should allow adding warnings to $WARNINGS" do
8
+ subject.warn "test1"
9
+
10
+ $WARNINGS.last.message.should == "test1"
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ gem 'rspec', '~> 2.4'
2
+ require 'rspec'
3
+ require 'warnings/version'
4
+
5
+ include Warnings
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'warnings/warning'
3
+
4
+ describe Warnings::Warning do
5
+ let(:source_file) { 'foo/bar.rb' }
6
+ let(:source_line) { 42 }
7
+ let(:source_method) { 'baz' }
8
+
9
+ subject do
10
+ described_class.new("foo", ["#{source_file}:#{source_line}: in `#{source_method}'"])
11
+ end
12
+
13
+ describe "#initialize" do
14
+ it "should parse the source-file" do
15
+ subject.source_file.should be == source_file
16
+ end
17
+
18
+ it "should parse the source-line" do
19
+ subject.source_line.should be == source_line
20
+ end
21
+
22
+ it "should parse the source-method" do
23
+ subject.source_method.should be == source_method
24
+ end
25
+ end
26
+
27
+ it "should provide a source_location method" do
28
+ subject.source_location.should be == [source_file, source_line]
29
+ end
30
+
31
+ it "should provide a #to_s method" do
32
+ subject.to_s.should be == subject.message
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'warnings'
3
+
4
+ describe Warnings do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+
9
+ it "should define a $WARNINGS global variable" do
10
+ $WARNINGS.should_not be_nil
11
+ end
12
+
13
+ it "should use an Array for $WARNINGS" do
14
+ $WARNINGS.should be_kind_of(Array)
15
+ end
16
+ end
data/warnings.gemspec ADDED
@@ -0,0 +1,127 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+ files = if File.directory?('.git')
7
+ `git ls-files`.split($/)
8
+ elsif File.directory?('.hg')
9
+ `hg manifest`.split($/)
10
+ elsif File.directory?('.svn')
11
+ `svn ls -R`.split($/).select { |path| File.file?(path) }
12
+ else
13
+ Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
14
+ end
15
+
16
+ filter_files = lambda { |paths|
17
+ case paths
18
+ when Array
19
+ (files & paths)
20
+ when String
21
+ (files & Dir[paths])
22
+ end
23
+ }
24
+
25
+ version = {
26
+ :file => 'lib/warnings/version.rb',
27
+ :constant => 'Warnings::VERSION'
28
+ }
29
+
30
+ defaults = {
31
+ 'name' => File.basename(File.dirname(__FILE__)),
32
+ 'files' => files,
33
+ 'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
34
+ 'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
35
+ 'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
36
+ }
37
+
38
+ metadata = defaults.merge(YAML.load_file('gemspec.yml'))
39
+
40
+ gemspec.name = metadata.fetch('name',defaults[:name])
41
+ gemspec.version = if metadata['version']
42
+ metadata['version']
43
+ elsif File.file?(version[:file])
44
+ require File.join('.',version[:file])
45
+ eval(version[:constant])
46
+ end
47
+
48
+ gemspec.summary = metadata.fetch('summary',metadata['description'])
49
+ gemspec.description = metadata.fetch('description',metadata['summary'])
50
+
51
+ case metadata['license']
52
+ when Array
53
+ gemspec.licenses = metadata['license']
54
+ when String
55
+ gemspec.license = metadata['license']
56
+ end
57
+
58
+ case metadata['authors']
59
+ when Array
60
+ gemspec.authors = metadata['authors']
61
+ when String
62
+ gemspec.author = metadata['authors']
63
+ end
64
+
65
+ gemspec.email = metadata['email']
66
+ gemspec.homepage = metadata['homepage']
67
+
68
+ case metadata['require_paths']
69
+ when Array
70
+ gemspec.require_paths = metadata['require_paths']
71
+ when String
72
+ gemspec.require_path = metadata['require_paths']
73
+ end
74
+
75
+ gemspec.files = filter_files[metadata['files']]
76
+
77
+ gemspec.executables = metadata['executables']
78
+ gemspec.extensions = metadata['extensions']
79
+
80
+ if Gem::VERSION < '1.7.'
81
+ gemspec.default_executable = gemspec.executables.first
82
+ end
83
+
84
+ gemspec.test_files = filter_files[metadata['test_files']]
85
+
86
+ unless gemspec.files.include?('.document')
87
+ gemspec.extra_rdoc_files = metadata['extra_doc_files']
88
+ end
89
+
90
+ gemspec.post_install_message = metadata['post_install_message']
91
+ gemspec.requirements = metadata['requirements']
92
+
93
+ if gemspec.respond_to?(:required_ruby_version=)
94
+ gemspec.required_ruby_version = metadata['required_ruby_version']
95
+ end
96
+
97
+ if gemspec.respond_to?(:required_rubygems_version=)
98
+ gemspec.required_rubygems_version = metadata['required_ruby_version']
99
+ end
100
+
101
+ parse_versions = lambda { |versions|
102
+ case versions
103
+ when Array
104
+ versions.map { |v| v.to_s }
105
+ when String
106
+ versions.split(/,\s*/)
107
+ end
108
+ }
109
+
110
+ if metadata['dependencies']
111
+ metadata['dependencies'].each do |name,versions|
112
+ gemspec.add_dependency(name,parse_versions[versions])
113
+ end
114
+ end
115
+
116
+ if metadata['runtime_dependencies']
117
+ metadata['runtime_dependencies'].each do |name,versions|
118
+ gemspec.add_runtime_dependency(name,parse_versions[versions])
119
+ end
120
+ end
121
+
122
+ if metadata['development_dependencies']
123
+ metadata['development_dependencies'].each do |name,versions|
124
+ gemspec.add_development_dependency(name,parse_versions[versions])
125
+ end
126
+ end
127
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warnings
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Postmodern
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-24 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ore-tasks
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: "0.4"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: "2.4"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: yard
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.7.0
46
+ type: :development
47
+ version_requirements: *id003
48
+ description: Warnings provides a searchable and more readable Warning Message facility for Ruby. With Warnings, one can save all warning messages generated by your code, search through them and print them upon exit.
49
+ email:
50
+ - postmodern.mod3@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - README.md
57
+ - ChangeLog.md
58
+ - LICENSE.txt
59
+ files:
60
+ - .document
61
+ - .rspec
62
+ - .yardopts
63
+ - ChangeLog.md
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - gemspec.yml
68
+ - lib/warnings.rb
69
+ - lib/warnings/mixin.rb
70
+ - lib/warnings/version.rb
71
+ - lib/warnings/warning.rb
72
+ - lib/warnings/warnings.rb
73
+ - spec/mixin_spec.rb
74
+ - spec/spec_helper.rb
75
+ - spec/warning_spec.rb
76
+ - spec/warnings_spec.rb
77
+ - warnings.gemspec
78
+ homepage: http://github.com/postmodern/warnings
79
+ licenses:
80
+ - MIT
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project: warnings
101
+ rubygems_version: 1.8.5
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Provides a better Warning Message facility for Ruby.
105
+ test_files:
106
+ - spec/mixin_spec.rb
107
+ - spec/warning_spec.rb
108
+ - spec/warnings_spec.rb