structured_warnings 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ doc
2
+ pkg
data/History.txt CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.1.3 2009-11-28
2
+
3
+ * major enhancements
4
+ * improved API of assert_warn and assert_no_warn
5
+
6
+ == 0.1.2 2009-11-27
7
+
8
+ * major enhancements
9
+ * moved to gemcutter
10
+ * minor enhancements
11
+ * removed all old cruft
12
+
1
13
  == 0.1.1 2008-02-22
2
14
 
3
15
  * 1 major enhancement:
data/README.rdoc ADDED
@@ -0,0 +1,128 @@
1
+ = Structured Warnings
2
+
3
+ This is an implementation of Daniel Berger's {proposal of structured warnings
4
+ for Ruby}[http://www.oreillynet.com/ruby/blog/2008/02/structured_warnings_now.html]. They provide dynamic suppression and activation, as well as, an
5
+ inheritance hierarchy to model their relations. This library preserves the old
6
+ <code>warn</code> signature, but additionally allows a <code>raise</code>-like
7
+ use.
8
+
9
+ For more information on the usage and benefits of this library have a look at
10
+ the inspiring article at O'Reilly.
11
+
12
+ http://www.oreillynet.com/ruby/blog/2008/02/structured_warnings_now.html
13
+
14
+ == Installation
15
+
16
+ gem install structured_warnings
17
+
18
+ == Example Usage
19
+
20
+ To get you started - here is a short example
21
+
22
+ In order to use structured_warnings in library code, use the following code.
23
+
24
+ # in lib/...
25
+ require 'structured_warnings'
26
+
27
+ class Foo
28
+ def old_method
29
+ warn DeprecatedMethodWarning, 'This method is deprecated. Use new_method instead'
30
+ # Do stuff
31
+ end
32
+ end
33
+
34
+ # in test/...
35
+ require 'test/unit'
36
+ require 'structured_warnings'
37
+
38
+ class FooTests < Test::Unit::TestCase
39
+ def setup
40
+ @foo = Foo.new
41
+ end
42
+
43
+ def test_old_method_emits_deprecation_warning
44
+ assert_warn(DeprecatedMethodWarning){ @foo.old_method }
45
+ end
46
+ end
47
+
48
+ DeprecatedMethodWarning is only one of multiple predefined warning types. You
49
+ may add your own types by subclassing Warning if you like.
50
+
51
+ Client code of your library will look as follows:
52
+
53
+ require "foo"
54
+
55
+ foo = Foo.new
56
+ foo.old_method # => will print
57
+ # ... `old_method' : This method is deprecated. Use new_method instead (DeprecatedMethodWarning)
58
+
59
+ But the main difference to the standard warning concept shipped with ruby, is
60
+ that the client is able to selectively disable certain warnings s/he is aware
61
+ of and not willing to fix.
62
+
63
+ DeprecatedMethodWarning.disable # Globally disable warnings about deprecated methods!
64
+
65
+ foo.old_method # => will print nothing
66
+
67
+ DeprecatedMethodWarning.enable # Reenable warnings again.
68
+
69
+ And there is an even more powerful option for your clients, the can selectively
70
+ disable warnings in a dynamic block scope.
71
+
72
+ # Don't bug me about deprecated method warnings within this block, I know
73
+ # what I'm doing.
74
+ #
75
+ DeprecatedMethodWarning.disable do
76
+ foo.old_method
77
+ end
78
+
79
+ These settings are scoped to the local thread (and all threads spawned in the
80
+ block scope) and automatically reset after the block.
81
+
82
+ == Detailed Documentation
83
+
84
+ Have closer look at the RDoc of StructuredWarnings::Kernel, Warning and
85
+ Warning::ClassMethods.
86
+
87
+ Part of this library is a set of different warnings:
88
+
89
+ * Warning
90
+ * StandardWarning
91
+ * DeprecationWarning
92
+ * DeprecatedMethodWarning
93
+ * DeprecatedSignatureWarning
94
+
95
+ You are encourage to use your own subclasses of Warning to give as much
96
+ feedback to your users as possible.
97
+
98
+
99
+ == Resources
100
+
101
+ * {Initial announcement}[http://www.nach-vorne.de/2008/2/21/ann-structured_warnings-0-1-0-released]
102
+ * {Inspiring article}[http://www.oreillynet.com/ruby/blog/2008/02/structured_warnings_now.html]
103
+ * {Project's website}[http://github.com/schmidt/structured_warnings/]
104
+ * {API doc}[http://rdoc.info/projects/schmidt/structured_warnings]
105
+ * {Build Status on RunCodeRun}[http://runcoderun.com/schmidt/structured_warnings]
106
+
107
+
108
+ == How to submit patches
109
+
110
+ In order to submit patches, please fork the repository on GitHub, add your
111
+ patches to your own copy and send a "Pull Request" afterwards. I will then try
112
+ to add your submissions as soon as possible. Patches containing corresponding
113
+ tests are always welcome.
114
+
115
+ Bug reports or general feature requests should be added using GitHub Issues.
116
+
117
+ == Known Issues
118
+
119
+ Although the library transparently coorperates with Ruby's built-in
120
+ <code>Kernel#warn</code>, it may not override +rb_warn+ which is used internally to emit
121
+ "method redefined", "void context", and "parenthesis" warnings. They may not be
122
+ manipulated by structured_warnings.
123
+
124
+ == License
125
+
126
+ This code is free to use under the terms of the MIT license.
127
+
128
+ :include: License.txt
data/Rakefile CHANGED
@@ -1,4 +1,38 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "structured_warnings"
8
+ gemspec.summary = "Provides structured warnings for Ruby, using an exception-like interface and hierarchy."
9
+ gemspec.description = "This is an implementation of Daniel Berger's proposal of structured warnings for Ruby."
10
+ gemspec.email = "ruby@schmidtwisser.de"
11
+ gemspec.homepage = "http://github.com/schmidt/structured_warnings"
12
+ gemspec.authors = ["Gregor Schmidt"]
13
+
14
+ gemspec.add_development_dependency('rake')
15
+ gemspec.add_development_dependency('jeweler', '>= 1.4.0')
16
+ end
17
+
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ desc "Run all tests"
24
+ task :test do
25
+ require 'rake/runtest'
26
+ Rake.run_tests 'test/**/*_test.rb'
27
+ end
28
+
29
+ desc 'Generate documentation for the structured_warnings gem.'
30
+ Rake::RDocTask.new(:doc) do |doc|
31
+ doc.rdoc_dir = 'doc'
32
+ doc.title = 'structured_warnings'
33
+ doc.options << '--line-numbers' << '--inline-source'
34
+ doc.rdoc_files.include('README.rdoc')
35
+ doc.rdoc_files.include('lib/**/*.rb')
36
+ end
37
+
38
+ task :default => :test
@@ -7,11 +7,9 @@ require "structured_warnings/warning"
7
7
 
8
8
 
9
9
  module StructuredWarnings
10
- # On initialization self.init is called. When a test module is defined, it
11
- # is a assumed, that <code>test/unit</code> is used and the warn assertions
12
- # are added to Test::Unit::TestCase. If you <code>require "test/unit"</code>
13
- # after +structured_warnings+ you have to call #StructuredWarnings::init_test
14
- # manually.
10
+ # If you <code>require "test/unit"</code> after +structured_warnings+ you
11
+ # have to <code>require "structured_warnings/test"</code> manually,
12
+ # otherwise the test extensions will be added automatically.
15
13
  module ClassMethods
16
14
  # Executes a block using the given warner. This may be used to suppress
17
15
  # warnings to stdout, but fetch them and redirect them to somewhere else.
@@ -62,31 +60,13 @@ module StructuredWarnings
62
60
  end
63
61
  end
64
62
  #:startdoc:
65
-
66
- protected
67
- # Initializes the StructuredWarnings library. Includes the Kernel extensions
68
- # into Object, sets the initial set of disabled_warnings (none) and
69
- # initializes the warner to an instance of StructuredWarnings::Warner
70
- def init
71
- unless Object < StructuredWarnings::Kernel
72
- Object.class_eval { include StructuredWarnings::Kernel }
73
- StructuredWarnings::disabled_warnings = []
74
- StructuredWarnings::warner = StructuredWarnings::Warner.new
75
- end
76
- init_test if defined? ::Test
77
- end
78
-
79
- # Initializes the StructuredWarnings test extensions - namely adds
80
- # StructuredWarnings::Test::Assertions to Test::Unit::TestCase
81
- def init_test
82
- require "structured_warnings/test.rb"
83
- ::Test::Unit::TestCase.class_eval do
84
- include StructuredWarnings::Test::Assertions
85
- end
86
- rescue NameError
87
- end
88
63
  end
89
64
  extend ClassMethods
65
+ end
90
66
 
91
- init
67
+ unless Object < StructuredWarnings::Kernel
68
+ Object.class_eval { include StructuredWarnings::Kernel }
69
+ StructuredWarnings::disabled_warnings = []
70
+ StructuredWarnings::warner = StructuredWarnings::Warner.new
92
71
  end
72
+ require "structured_warnings/test" if defined? Test::Unit::TestCase
@@ -40,7 +40,7 @@ module StructuredWarnings
40
40
  #
41
41
  def warn(*args)
42
42
  first = args.shift
43
- if first.is_a? Class and first < Warning
43
+ if first.is_a? Class and first <= Warning
44
44
  warning = first
45
45
  message = args.shift
46
46
 
@@ -1,2 +1,7 @@
1
+ require "structured_warnings"
1
2
  require "structured_warnings/test/warner.rb"
2
3
  require "structured_warnings/test/assertions.rb"
4
+
5
+ Test::Unit::TestCase.class_eval do
6
+ include StructuredWarnings::Test::Assertions
7
+ end
@@ -2,8 +2,13 @@ module StructuredWarnings
2
2
  # This module ecapsulates all extensions to support <code>test/unit</code>.
3
3
  module Test
4
4
  module Assertions
5
- # Asserts that no warning was emmitted. It may be restricted to a certain
6
- # subtree of warnings.
5
+ # :call-seq:
6
+ # assert_no_warn(message = nil) {|| ...}
7
+ # assert_no_warn(warning_class, message) {|| ...}
8
+ # assert_no_warn(warning_instance) {|| ...}
9
+ #
10
+ # Asserts that the given warning was not emmitted. It may be restricted
11
+ # to a certain subtree of warnings and/or message.
7
12
  #
8
13
  # def foo
9
14
  # warn DeprecatedMethodWarning, "used foo, use bar instead"
@@ -14,34 +19,80 @@ module StructuredWarnings
14
19
  #
15
20
  # assert_no_warn(DeprecationWarning) { foo } # fails
16
21
  # assert_no_warn() { foo } # fails
17
- def assert_no_warn(warning = Warning)
22
+ #
23
+ # See assert_warn for more examples.
24
+ def assert_no_warn(*args)
25
+ warning, message = parse_arguments(args)
26
+
18
27
  w = StructuredWarnings::Test::Warner.new
19
28
  StructuredWarnings::with_warner(w) do
20
29
  yield
21
30
  end
22
- assert !w.warned?(warning), "#{warning} has been emitted."
31
+ assert !w.warned?(warning, message), "#{warning} has been emitted."
23
32
  end
24
33
 
25
- # Asserts that a warning was emmitted. It may be restricted to a certain
26
- # subtree of warnings.
34
+ # :call-seq:
35
+ # assert_warn(message = nil) {|| ...}
36
+ # assert_warn(warning_class, message) {|| ...}
37
+ # assert_warn(warning_instance) {|| ...}
38
+ #
39
+ # Asserts that the given warning was emmitted. It may be restricted to a
40
+ # certain subtree of warnings and/or message.
27
41
  #
28
42
  # def foo
29
43
  # warn DeprecatedMethodWarning, "used foo, use bar instead"
30
44
  # bar
31
45
  # end
32
46
  #
33
- # assert_warn(DeprecatedMethodWarning) { foo } # passes
34
- # assert_warn(DeprecationWarning) { foo } # passes
35
- # assert_warn() { foo } # passes
47
+ # # passes
48
+ # assert_warn(DeprecatedMethodWarning) { foo }
49
+ # assert_warn(DeprecationWarning) { foo }
50
+ # assert_warn() { foo }
51
+ # assert_warn(Warning, "used foo, use bar instead") { foo }
52
+ # assert_warn(Warning, /use bar/) { foo }
53
+ # assert_warn(Warning.new("used foo, use bar instead")) { foo }
36
54
  #
37
- # assert_warn(StandardWarning) { foo } # fails
55
+ # # fails
56
+ # assert_warn(StandardWarning) { foo }
57
+ # assert_warn(Warning, /deprecated/) { foo }
58
+ # assert_warn(Warning.new) { foo }
38
59
  #
39
- def assert_warn(warning = Warning)
60
+ def assert_warn(*args)
61
+ warning, message = parse_arguments(args)
62
+
40
63
  w = StructuredWarnings::Test::Warner.new
41
64
  StructuredWarnings::with_warner(w) do
42
65
  yield
43
66
  end
44
- assert w.warned?(warning), "#{warning} has not been emitted."
67
+ assert w.warned?(warning, message), "#{warning} has not been emitted."
68
+ end
69
+
70
+ private
71
+ def parse_arguments(args)
72
+ first = args.shift
73
+ if first.is_a? Class and first <= Warning
74
+ warning = first
75
+ message = args.shift
76
+
77
+ elsif first.is_a? Warning
78
+ warning = first.class
79
+ message = first.message
80
+
81
+ elsif first.is_a? String
82
+ warning = StandardWarning
83
+ message = first
84
+
85
+ else
86
+ warning = Warning
87
+ message = nil
88
+ end
89
+
90
+ unless args.empty?
91
+ raise ArgumentError,
92
+ "wrong number of arguments (#{args.size + 2} for 2)"
93
+ end
94
+
95
+ return warning, message
45
96
  end
46
97
  end
47
98
  end
@@ -8,13 +8,22 @@ module StructuredWarnings
8
8
  # method always returns nil to avoid warnings on stdout during assert_warn
9
9
  # and assert_no_warn blocks.
10
10
  def format(warning, message, call_stack)
11
- given_warnings << warning
11
+ given_warnings << warning.new(message)
12
12
  nil
13
13
  end
14
14
 
15
15
  # Returns true if any warning or a subclass of warning was emitted.
16
- def warned?(warning)
17
- given_warnings.any? {|w| (w <= warning)}
16
+ def warned?(warning, message = nil)
17
+ case message
18
+ when Regexp
19
+ given_warnings.any? {|w| w.is_a?(warning) && w.message =~ message}
20
+ when String
21
+ given_warnings.any? {|w| w.is_a?(warning) && w.message == message}
22
+ when nil
23
+ given_warnings.any? {|w| w.is_a?(warning)}
24
+ else
25
+ raise ArgumentError, "Unkown argument for 'message'"
26
+ end
18
27
  end
19
28
 
20
29
  # :stopdoc:
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{structured_warnings}
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Gregor Schmidt"]
12
+ s.date = %q{2009-11-28}
13
+ s.description = %q{This is an implementation of Daniel Berger's proposal of structured warnings for Ruby.}
14
+ s.email = %q{ruby@schmidtwisser.de}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "History.txt",
21
+ "License.txt",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "lib/structured_warnings.rb",
25
+ "lib/structured_warnings/dynamic.rb",
26
+ "lib/structured_warnings/kernel.rb",
27
+ "lib/structured_warnings/test.rb",
28
+ "lib/structured_warnings/test/assertions.rb",
29
+ "lib/structured_warnings/test/warner.rb",
30
+ "lib/structured_warnings/warner.rb",
31
+ "lib/structured_warnings/warning.rb",
32
+ "structured_warnings.gemspec",
33
+ "test/structured_warnings_test.rb",
34
+ "test/test_helper.rb",
35
+ "version.yml"
36
+ ]
37
+ s.homepage = %q{http://github.com/schmidt/structured_warnings}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.5}
41
+ s.summary = %q{Provides structured warnings for Ruby, using an exception-like interface and hierarchy.}
42
+ s.test_files = [
43
+ "test/structured_warnings_test.rb",
44
+ "test/test_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<rake>, [">= 0"])
53
+ s.add_development_dependency(%q<jeweler>, [">= 1.4.0"])
54
+ else
55
+ s.add_dependency(%q<rake>, [">= 0"])
56
+ s.add_dependency(%q<jeweler>, [">= 1.4.0"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<rake>, [">= 0"])
60
+ s.add_dependency(%q<jeweler>, [">= 1.4.0"])
61
+ end
62
+ end
63
+