yell 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -3,10 +3,7 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in yell.gemspec
4
4
  gemspec
5
5
 
6
-
7
- group :development do
6
+ group :development, :test do
8
7
  gem "rake"
8
+ end
9
9
 
10
- gem "rspec", "~> 2"
11
- gem "timecop"
12
- end
data/Rakefile CHANGED
@@ -3,7 +3,27 @@ $LOAD_PATH.unshift( 'lib' )
3
3
  require 'bundler'
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- # === RSpec
6
+ task :examples do
7
+ require 'benchmark'
8
+
9
+ seconds = Benchmark.realtime do
10
+ Dir[ './examples/*.rb' ].sort.each do |file|
11
+ begin
12
+ puts "\n*** Running #{file}"
13
+
14
+ require file
15
+ rescue Exception => e
16
+ puts "#{e.class}: #{e.message}:\n\t#{e.backtrace.join("\n\t")}"
17
+
18
+ exit 1
19
+ end
20
+ end
21
+ end
22
+
23
+ puts "\n\t[ Examples took #{seconds} seconds to run ]"
24
+ end
25
+
26
+ # RSpec
7
27
  begin
8
28
  require 'rspec/core/rake_task'
9
29
 
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../lib/yell'
4
+
5
+ puts <<-EOS
6
+
7
+ You may colorize the log output on your io-based loggers loke so:
8
+
9
+ logger = Yell.new STDOUT, :colors => true
10
+
11
+ [:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
12
+ logger.send level, level
13
+ end
14
+
15
+ EOS
16
+
17
+ puts "=== actuale example ==="
18
+ logger = Yell.new STDOUT, :colors => true
19
+
20
+ [:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
21
+ logger.send level, level
22
+ end
23
+
data/lib/yell.rb CHANGED
@@ -24,12 +24,6 @@
24
24
  require 'time'
25
25
  require 'socket'
26
26
 
27
- require File.dirname(__FILE__) + '/yell/event'
28
- require File.dirname(__FILE__) + '/yell/level'
29
- require File.dirname(__FILE__) + '/yell/formatter'
30
- require File.dirname(__FILE__) + '/yell/adapters'
31
- require File.dirname(__FILE__) + '/yell/logger'
32
-
33
27
  module Yell #:nodoc:
34
28
  Severities = [ 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN' ]
35
29
 
@@ -73,3 +67,9 @@ module Yell #:nodoc:
73
67
 
74
68
  end
75
69
 
70
+ require File.dirname(__FILE__) + '/yell/event'
71
+ require File.dirname(__FILE__) + '/yell/level'
72
+ require File.dirname(__FILE__) + '/yell/formatter'
73
+ require File.dirname(__FILE__) + '/yell/adapters'
74
+ require File.dirname(__FILE__) + '/yell/logger'
75
+
@@ -3,23 +3,115 @@
3
3
  module Yell #:nodoc:
4
4
  module Adapters #:nodoc:
5
5
 
6
- # This class provides the basic interface for all allowed
7
- # operations on any adapter implementation.
6
+ # This class provides the basic interface for all allowed operations on any
7
+ # adapter implementation. Other adapters should inherit from it for the methods
8
+ # used by the {Yell::Logger}.
8
9
  #
9
- # Other adapters should inherit from it for the methods used
10
- # by the {Yell::Logger}.
10
+ # Writing your own adapter is really simple. Inherit from the base class and use
11
+ # the `setup`, `write` and `close` methods. Yell requires the `write` method to be
12
+ # specified (`setup` and `close` are optional).
13
+ #
14
+ #
15
+ # The following example shows how to define a basic Adapter to format and print
16
+ # log events to STDOUT:
17
+ #
18
+ # class PutsAdapter < Yell::Adapters::Base
19
+ # include Yell::Formatter::Helpers
20
+ #
21
+ # setup do |options|
22
+ # self.format = options[:format]
23
+ # end
24
+ #
25
+ # write do |event|
26
+ # message = format.format(event)
27
+ #
28
+ # STDOUT.puts message
29
+ # end
30
+ # end
31
+ #
32
+ #
33
+ # After the Adapter has been written, we need to register it to Yell:
34
+ #
35
+ # Yell::Adapters.register :puts, PutsAdapter
36
+ #
37
+ # Now, we can use it like so:
38
+ #
39
+ # logger = Yell.new :puts
40
+ # logger.info "Hello World!"
11
41
  class Base
42
+ include Yell::Level::Helpers
43
+
44
+ class << self
45
+ # Setup your adapter with this helper method.
46
+ #
47
+ # @example
48
+ # setup do |options|
49
+ # @file_handle = File.new( '/dev/null', 'w' )
50
+ # end
51
+ def setup( &block )
52
+ compile!( :setup!, &block )
53
+ end
54
+
55
+ # Define your write method with this helper.
56
+ #
57
+ # @example Printing messages to file
58
+ # write do |event|
59
+ # @file_handle.puts event.message
60
+ # end
61
+ def write( &block )
62
+ compile!( :write!, &block )
63
+ end
64
+
65
+ # Define your close method with this helper.
66
+ #
67
+ # @example Closing a file handle
68
+ # close do
69
+ # @file_handle.close
70
+ # end
71
+ def close( &block )
72
+ compile!( :close!, &block )
73
+ end
74
+
75
+
76
+ private
77
+
78
+ # Pretty funky code block, I know but here is what it basically does:
79
+ #
80
+ # @example
81
+ # compile! :write! do |event|
82
+ # puts event.message
83
+ # end
84
+ #
85
+ # # Is actually defining the `:write!` instance method with a call to super:
86
+ #
87
+ # def write!( event )
88
+ # puts event.method
89
+ # super
90
+ # end
91
+ def compile!( name, &block )
92
+ # Get the already defined method
93
+ m = instance_method name
94
+
95
+ # Create a new method with leading underscore
96
+ define_method "_#{name}", &block
97
+ _m = instance_method "_#{name}"
98
+ remove_method "_#{name}"
99
+
100
+ # Define instance method
101
+ if block.arity == 0
102
+ define_method(name) { _m.bind(self).call; m.bind(self).call }
103
+ else
104
+ define_method(name) { |*args| _m.bind(self).call(*args); m.bind(self).call(*args) }
105
+ end
106
+ end
107
+ end
12
108
 
13
- # Accessor to the level
14
- attr_reader :level
15
-
16
- # Accessor to the options
17
- attr_reader :options
18
109
 
110
+ # Initializes a new Adapter.
111
+ #
112
+ # You should not overload the constructor, use #setup instead.
19
113
  def initialize( options = {}, &block )
20
- @options = options
21
-
22
- self.level = options[:level]
114
+ setup!(options)
23
115
 
24
116
  block.call(self) if block
25
117
  end
@@ -30,6 +122,11 @@ module Yell #:nodoc:
30
122
  # actually write or not.
31
123
  def write( event )
32
124
  write!( event ) if write?( event )
125
+ rescue Exception => e
126
+ # make sure the adapter is closed and re-raise the exception
127
+ close
128
+
129
+ raise( e )
33
130
  end
34
131
 
35
132
  # Close the adapter (stream, connection, etc).
@@ -37,28 +134,34 @@ module Yell #:nodoc:
37
134
  # Adapter classes should provide their own implementation
38
135
  # of this method.
39
136
  def close
40
- raise 'Not implemented'
41
- end
42
-
43
- # Set the log level.
44
- #
45
- # @example Set minimum level to :info
46
- # level :info
47
- #
48
- # For more examples, refer to {Yell::Level}.
49
- def level=( severity )
50
- @level = Yell::Level.new( severity )
137
+ close!
51
138
  end
52
139
 
53
140
 
54
141
  private
55
142
 
56
- # The perform the actual write.
143
+ # Setup the adapter instance.
57
144
  #
58
145
  # Adapter classes should provide their own implementation
146
+ # of this method (if applicable).
147
+ def setup!( options )
148
+ self.level = options[:level]
149
+ end
150
+
151
+ # Perform the actual write.
152
+ #
153
+ # Adapter classes must provide their own implementation
59
154
  # of this method.
60
155
  def write!( event )
61
- raise 'Not implemented'
156
+ # Not implemented
157
+ end
158
+
159
+ # Perform the actual close.
160
+ #
161
+ # Adapter classes should provide their own implementation
162
+ # of this method.
163
+ def close!
164
+ # Not implemented
62
165
  end
63
166
 
64
167
  # Determine whether to write at the given severity.
@@ -10,34 +10,26 @@ module Yell #:nodoc:
10
10
  # The default date pattern, e.g. "19820114" (14 Jan 1982)
11
11
  DefaultDatePattern = "%Y%m%d"
12
12
 
13
- def initialize( options = {}, &block )
13
+ setup do |options|
14
14
  @date_pattern = options[:date_pattern] || DefaultDatePattern
15
15
 
16
16
  @file_basename = options[:filename] || default_filename
17
17
  options[:filename] = @file_basename
18
18
 
19
19
  @date = nil # default; do not override --R
20
-
21
- super
22
20
  end
23
21
 
24
- # @overload Reset the file handle
25
- def close
26
- @filename = new_filename
22
+ write do |event|
23
+ close if close?
24
+ end
27
25
 
28
- super
26
+ close do
27
+ @filename = @file_basename.sub( /(\.\w+)?$/, ".#{@date}\\1" )
29
28
  end
30
29
 
31
30
 
32
31
  private
33
32
 
34
- # @overload Close the file if date is expired
35
- def write!( event )
36
- close if close?
37
-
38
- super( event )
39
- end
40
-
41
33
  # Determines whether to close the file handle or not.
42
34
  #
43
35
  # It is based on the `:date_pattern` (can be passed as option upon initialize).
@@ -54,11 +46,6 @@ module Yell #:nodoc:
54
46
  false
55
47
  end
56
48
 
57
- # Sets the filename with the `:date_pattern` appended to it.
58
- def new_filename
59
- @file_basename.sub( /(\.\w+)?$/, ".#{@date}\\1" )
60
- end
61
-
62
49
  end
63
50
 
64
51
  register( :datefile, Yell::Adapters::Datefile )
@@ -7,20 +7,18 @@ module Yell #:nodoc:
7
7
  # for logging into files.
8
8
  class File < Yell::Adapters::Io
9
9
 
10
- def initialize( options = {}, &block )
11
- super
12
-
10
+ setup do |options|
13
11
  @filename = options.fetch(:filename, default_filename)
14
12
  end
15
13
 
14
+
15
+ private
16
+
16
17
  # @overload Lazily open the file handle
17
18
  def stream
18
19
  @stream ||= ::File.open( @filename, ::File::WRONLY|::File::APPEND|::File::CREAT )
19
20
  end
20
21
 
21
-
22
- private
23
-
24
22
  def default_filename #:nodoc:
25
23
  ::File.directory?("log") ? "log/#{Yell.env}.log" : "#{Yell.env}.log"
26
24
  end
@@ -4,6 +4,7 @@ module Yell #:nodoc:
4
4
  module Adapters #:nodoc:
5
5
 
6
6
  class Io < Yell::Adapters::Base
7
+ include Yell::Formatter::Helpers
7
8
 
8
9
  # The possible unix log colors
9
10
  Colors = {
@@ -16,73 +17,47 @@ module Yell #:nodoc:
16
17
  'DEFAULT' => "\e[0m" # NONE
17
18
  }
18
19
 
19
- # Accessor to the formatter
20
- attr_reader :format
21
-
22
- def initialize( options = {}, &block )
23
- colorize options.fetch(:colorize, false)
24
-
20
+ setup do |options|
21
+ self.colors = options[:colors]
25
22
  self.format = options[:format]
26
-
27
- super( options, &block )
28
23
  end
29
24
 
30
- # The IO stream
31
- #
32
- # Adapter classes should provide their own implementation
33
- # of this method.
34
- def stream
35
- raise 'Not implemented'
36
- end
25
+ write do |event|
26
+ message = format.format(event)
37
27
 
38
- # Close the io stream
39
- def close
40
- @stream.close if @stream.respond_to? :close
28
+ # colorize if applicable
29
+ if colors and color = Colors[event.level]
30
+ message = color + message + Colors['DEFAULT']
31
+ end
41
32
 
42
- @stream = nil
43
- end
33
+ message << "\n" unless message[-1] == ?\n # add new line if there is none
44
34
 
45
- # Set the format for your message.
46
- def format=( pattern )
47
- @format = case pattern
48
- when Yell::Formatter then pattern
49
- when false then Yell::Formatter.new( "%m" )
50
- else Yell::Formatter.new( *pattern )
51
- end
35
+ stream.print( message )
36
+ stream.flush
52
37
  end
53
38
 
54
- # Enable colorizing the log output.
55
- def colorize( color = true )
56
- @colorize = color
39
+ close do
40
+ @stream.close if @stream.respond_to? :close
41
+ @stream = nil
57
42
  end
58
- alias :colorize! :colorize
59
43
 
60
44
 
61
- private
62
-
63
- # The method formats the message and writes it to the file handle.
64
- def write!( event )
65
- message = @format.format( event )
45
+ attr_accessor :colors
66
46
 
67
- # colorize if applicable
68
- if colorize? and color = Colors[event.level]
69
- message = color + message + Colors['DEFAULT']
70
- end
47
+ # Shortcut to enable colors
48
+ def colorize!; @colors = true; end
71
49
 
72
- message << "\n" unless message[-1] == ?\n # add new line if there is none
73
50
 
74
- stream.print( message )
75
- stream.flush
76
- # rescue Exception => e
77
- # close
51
+ private
78
52
 
79
- # # re-raise the exception
80
- # raise( e, caller )
53
+ # The IO stream
54
+ #
55
+ # Adapter classes should provide their own implementation
56
+ # of this method.
57
+ def stream
58
+ raise 'Not implemented'
81
59
  end
82
60
 
83
- # Determie whether to colorize the log output or nor
84
- def colorize?; !!@colorize; end
85
-
86
61
  end
87
62
 
88
63
  end
@@ -5,6 +5,8 @@ module Yell #:nodoc:
5
5
 
6
6
  class Stdout < Yell::Adapters::Io
7
7
 
8
+ private
9
+
8
10
  # @overload Lazily open the STDOUT stream
9
11
  def stream
10
12
  @stream ||= $stdout.clone
@@ -13,6 +15,8 @@ module Yell #:nodoc:
13
15
 
14
16
  class Stderr < Yell::Adapters::Io
15
17
 
18
+ private
19
+
16
20
  # @overload Lazily open the STDERR stream
17
21
  def stream
18
22
  @stream ||= $stderr.clone
@@ -44,6 +44,19 @@ module Yell #:nodoc:
44
44
 
45
45
  # The +Formatter+ provides a handle to configure your log message style.
46
46
  class Formatter
47
+ module Helpers
48
+ # Accessor to the format
49
+ attr_reader :format
50
+
51
+ # Set the format for your message.
52
+ def format=( pattern )
53
+ @format = case pattern
54
+ when Yell::Formatter then pattern
55
+ when false then Yell::Formatter.new( Yell::NoFormat )
56
+ else Yell::Formatter.new( *pattern )
57
+ end
58
+ end
59
+ end
47
60
 
48
61
  PatternTable = {
49
62
  "m" => "event.message", # Message
@@ -74,6 +87,7 @@ module Yell #:nodoc:
74
87
  define!
75
88
  end
76
89
 
90
+
77
91
  private
78
92
 
79
93
  # defines the format method
data/lib/yell/level.rb CHANGED
@@ -23,6 +23,23 @@ module Yell #:nodoc:
23
23
  # @example Set at :info only
24
24
  # Yell::Level.new.at(:info)
25
25
  class Level
26
+ module Helpers
27
+ # Accessor to the log level
28
+ attr_reader :level
29
+
30
+ # Set the minimum log level.
31
+ #
32
+ # @example Set the level to :warn
33
+ # level = :warn
34
+ #
35
+ # @param [String, Symbol, Integer] val The minimum log level
36
+ def level=( severity )
37
+ @level = case severity
38
+ when Yell::Level then severity
39
+ else Yell::Level.new( severity )
40
+ end
41
+ end
42
+ end
26
43
 
27
44
  attr_reader :severities
28
45
 
@@ -42,16 +59,19 @@ module Yell #:nodoc:
42
59
  #
43
60
  # @param [Integer,String,Symbol,Array,Range,nil] severity The severity for the level.
44
61
  def initialize( severity = nil )
45
- @severities = Yell::Severities.map { true } # all levels allowed by default
62
+ reset!
46
63
 
47
64
  case severity
48
- when Yell::Level then @severities = severity.severities
49
65
  when Array then at( *severity )
50
66
  when Range then gte(severity.first).lte(severity.last)
51
67
  when Integer, String, Symbol then gte(severity)
52
68
  end
53
69
  end
54
70
 
71
+ def reset!
72
+ @severities = Yell::Severities.map { true }
73
+ end
74
+
55
75
  # Returns whether the level is allowed at the given severity
56
76
  #
57
77
  # @example
data/lib/yell/logger.rb CHANGED
@@ -29,9 +29,7 @@ module Yell #:nodoc:
29
29
  # l.level = :info
30
30
  # end
31
31
  class Logger
32
-
33
- # Accessor to the log level
34
- attr_reader :level
32
+ include Yell::Level::Helpers
35
33
 
36
34
  def initialize( *args, &block )
37
35
  @adapters = []
@@ -51,10 +49,11 @@ module Yell #:nodoc:
51
49
  self.adapter args.pop if args.any?
52
50
 
53
51
  # eval the given block
54
- # block.call(self) if block
55
- _call( &block ) if block
52
+ block.call(self) if block
53
+ # _call( &block ) if block
56
54
 
57
- define!
55
+ # default adapter when none defined
56
+ adapter :file if @adapters.empty?
58
57
  end
59
58
 
60
59
  # Define an adapter to be used for logging.
@@ -87,16 +86,6 @@ module Yell #:nodoc:
87
86
  @adapters << Yell::Adapters.new( type, options, &block )
88
87
  end
89
88
 
90
- # Set the minimum log level.
91
- #
92
- # @example Set the level to :warn
93
- # level = :warn
94
- #
95
- # @param [String, Symbol, Integer] val The minimum log level
96
- def level=( severity )
97
- @level = Yell::Level.new( severity )
98
- end
99
-
100
89
  # Deprecated: Use attr_reader in future
101
90
  def level( val = nil )
102
91
  if val.nil?
@@ -119,6 +108,28 @@ module Yell #:nodoc:
119
108
  @adapters.each(&:close)
120
109
  end
121
110
 
111
+ # Creates instance methods for every log level:
112
+ # `debug` and `debug?`
113
+ # `info` and `info?`
114
+ # `warn` and `warn?`
115
+ # `error` and `error?`
116
+ # `unknown` and `unknown?`
117
+ Yell::Severities.each_with_index do |s, index|
118
+ name = s.downcase
119
+
120
+ class_eval <<-EOS, __FILE__, __LINE__
121
+ def #{name}?; @level.at?(#{index}); end # def info?; @level.at?(1); end
122
+ #
123
+ def #{name}( m = nil, &b ) # def info( m = nil, &b )
124
+ return unless #{name}? # return unless info?
125
+ #
126
+ write Yell::Event.new( '#{s}', m, &b ) # write Yell::Event.new( "INFO", m, &b )
127
+ #
128
+ true # true
129
+ end # end
130
+ EOS
131
+ end
132
+
122
133
 
123
134
  private
124
135
 
@@ -136,34 +147,6 @@ module Yell #:nodoc:
136
147
  end
137
148
  end
138
149
 
139
- # Sets a default adapter if none was given explicitly and defines the log methods on
140
- # the logger instance.
141
- def define!
142
- adapter :file if @adapters.empty? # default adapter when none defined
143
-
144
- define_log_methods!
145
- end
146
-
147
- # Creates instance methods for every defined log level (debug, info, ...) depending
148
- # on whether anything should be logged upon, for instance, #info.
149
- def define_log_methods!
150
- Yell::Severities.each_with_index do |s, index|
151
- name = s.downcase
152
-
153
- instance_eval %-
154
- def #{name}?; @level.at?(#{index}); end # def info?; @level.at?(1); end
155
- #
156
- def #{name}( m = nil, &b ) # def info( m = nil, &b )
157
- return unless #{name}? # return unless info?
158
- #
159
- write Yell::Event.new( '#{s}', m, &b ) # write Yell::Event.new( "INFO", m, &b )
160
- #
161
- true # true
162
- end # end
163
- -
164
- end
165
- end
166
-
167
150
  # Cycles all the adapters and writes the message
168
151
  def write( event )
169
152
  @adapters.each { |a| a.write(event) }
data/lib/yell/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Yell #:nodoc:
4
- VERSION = "0.5.1"
4
+ VERSION = "0.6.0"
5
5
 
6
6
  end
7
7
 
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $:.unshift File.expand_path('..', __FILE__)
2
2
  $:.unshift File.expand_path('../../lib', __FILE__)
3
3
 
4
+ require 'ostruct'
5
+
4
6
  require 'yell'
5
7
 
6
8
  require 'rspec'
@@ -10,5 +12,8 @@ require 'timecop'
10
12
  RSpec.configure do |config|
11
13
  config.mock_framework = :rr
12
14
 
15
+ config.after do
16
+ Dir[ "*.log" ].each { |f| File.delete f }
17
+ end
13
18
  end
14
19
 
@@ -55,13 +55,5 @@ describe Yell::Adapters::Base do
55
55
  end
56
56
  end
57
57
 
58
- context :close do
59
- subject { Yell::Adapters::Base.new.close }
60
-
61
- it "should raise" do
62
- lambda { subject }.should raise_error("Not implemented" )
63
- end
64
- end
65
-
66
58
  end
67
59
 
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yell::Adapters::Datefile do
4
+ let( :time ) { Time.now }
5
+ let( :filename ) { 'filename.log' }
6
+
7
+ let( :event ) { Yell::Event.new("INFO", "Hello World") }
8
+
9
+ describe :filename do
10
+ let( :adapter ) { Yell::Adapters::Datefile.new(:filename => filename) }
11
+ let( :date_filename ) { "filename.#{time.strftime(Yell::Adapters::Datefile::DefaultDatePattern)}.log" }
12
+
13
+ before do
14
+ Timecop.freeze( time )
15
+ end
16
+
17
+ it "should be replaced with date_pattern" do
18
+ adapter.write( event )
19
+
20
+ File.exist?(date_filename).should be_true
21
+ end
22
+
23
+ it "should open file handle only once" do
24
+ mock( File ).open( date_filename, anything ) { File.new('/dev/null', 'w') }
25
+
26
+ adapter.write( event )
27
+ adapter.write( event )
28
+ end
29
+
30
+ context "rollover" do
31
+ let( :tomorrow ) { time + 86400 }
32
+ let( :tomorrow_date_filename ) { "filename.#{tomorrow.strftime(Yell::Adapters::Datefile::DefaultDatePattern)}.log" }
33
+
34
+ it "should rollover when date has passed" do
35
+ mock( File ).open( date_filename, anything ) { File.new('/dev/null', 'w') }
36
+ adapter.write( event )
37
+
38
+ Timecop.freeze( tomorrow ) # tomorrow
39
+
40
+ mock( File ).open( tomorrow_date_filename, anything ) { File.new('/dev/null', 'w') }
41
+ adapter.write( event )
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yell::Adapters::File do
4
+ let( :devnull ) { File.new('/dev/null', 'w') }
5
+
6
+ before do
7
+ stub( File ).open( anything, anything ) { devnull }
8
+ end
9
+
10
+ it { should be_kind_of Yell::Adapters::Io }
11
+
12
+ context :stream do
13
+ subject { Yell::Adapters::File.new.send :stream }
14
+
15
+ it { should be_kind_of File }
16
+ end
17
+
18
+ context :write do
19
+ let( :event ) { Yell::Event.new("INFO", "Hello World") }
20
+
21
+ context "default filename" do
22
+ let( :filename ) { "#{Yell.env}.log" }
23
+ let( :adapter ) { Yell::Adapters::File.new }
24
+
25
+ it "should print to file" do
26
+ mock( File ).open( filename, File::WRONLY|File::APPEND|File::CREAT ) { devnull }
27
+
28
+ adapter.write( event )
29
+ end
30
+ end
31
+
32
+ context "with given filename" do
33
+ let( :filename ) { 'filename.log' }
34
+ let( :adapter ) { Yell::Adapters::File.new( :filename => filename ) }
35
+
36
+ it "should print to file" do
37
+ mock( File ).open( filename, File::WRONLY|File::APPEND|File::CREAT ) { devnull }
38
+
39
+ adapter.write( event )
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yell::Adapters::Io do
4
+
5
+ it { should be_kind_of Yell::Adapters::Base }
6
+
7
+ context "initialize" do
8
+ it "should set default :format" do
9
+ adapter = Yell::Adapters::Io.new
10
+
11
+ adapter.format.should be_kind_of Yell::Formatter
12
+ end
13
+
14
+ context :level do
15
+ let( :level ) { Yell::Level.new(:warn) }
16
+
17
+ it "should set the level" do
18
+ adapter = Yell::Adapters::Io.new :level => level
19
+ adapter.level.should == level
20
+ end
21
+
22
+ it "should set the level when block was given" do
23
+ adapter = Yell::Adapters::Io.new { |a| a.level = level }
24
+ adapter.level.should == level
25
+ end
26
+ end
27
+
28
+ context :format do
29
+ let( :format ) { Yell::Formatter.new }
30
+
31
+ it "should set the level" do
32
+ adapter = Yell::Adapters::Io.new :format => format
33
+ adapter.format.should == format
34
+ end
35
+
36
+ it "should set the level when block was given" do
37
+ adapter = Yell::Adapters::Io.new { |a| a.format = format }
38
+ adapter.format.should == format
39
+ end
40
+ end
41
+ end
42
+
43
+ context :stream do
44
+ it "should raise" do
45
+ lambda { Yell::Adapters::Io.new.send :stream }.should raise_error("Not implemented" )
46
+ end
47
+ end
48
+
49
+ context :write do
50
+ let( :event ) { Yell::Event.new("INFO", "Hello World") }
51
+ let( :adapter ) { Yell::Adapters::Io.new }
52
+ let( :stream ) { File.new('/dev/null', 'w') }
53
+
54
+ before do
55
+ stub( adapter ).stream { stream }
56
+ end
57
+
58
+ it "should format the message" do
59
+ mock.proxy( adapter.format ).format( event )
60
+
61
+ adapter.write( event )
62
+ end
63
+
64
+ it "should print formatted message to stream" do
65
+ formatted = Yell::Formatter.new.format( event )
66
+
67
+ mock( stream ).print( formatted << "\n" )
68
+ mock( stream ).flush
69
+
70
+ adapter.write( event )
71
+ end
72
+ end
73
+
74
+ end
75
+
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yell::Adapters::Stdout do
4
+
5
+ it { should be_kind_of Yell::Adapters::Io }
6
+
7
+ context :stream do
8
+ subject { Yell::Adapters::Stdout.new.send :stream }
9
+
10
+ it { should be_kind_of IO }
11
+ end
12
+
13
+ end
14
+
15
+ describe Yell::Adapters::Stderr do
16
+
17
+ it { should be_kind_of Yell::Adapters::Io }
18
+
19
+ context :stream do
20
+ subject { Yell::Adapters::Stderr.new.send :stream }
21
+
22
+ it { should be_kind_of IO }
23
+ end
24
+
25
+ end
26
+
@@ -75,15 +75,15 @@ describe Yell::Logger do
75
75
  let( :level ) { Yell::Level.new :error }
76
76
  let( :adapter ) { Yell::Adapters::Stdout.new }
77
77
 
78
- let( :logger ) do
79
- Yell::Logger.new do |l|
78
+ let( :logger ) do
79
+ Yell::Logger.new do |l|
80
80
  l.level = level
81
81
  l.adapter adapter
82
82
  end
83
83
  end
84
84
 
85
85
  it "should set the level" do
86
- logger.level.severities.should == level.severities
86
+ logger.level.should == level
87
87
  end
88
88
 
89
89
  it "should define adapter" do
data/yell.gemspec CHANGED
@@ -21,4 +21,5 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_development_dependency "rspec"
23
23
  s.add_development_dependency "rr"
24
+ s.add_development_dependency "timecop"
24
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-03 00:00:00.000000000 Z
12
+ date: 2012-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70134284271320 !ruby/object:Gem::Requirement
16
+ requirement: &17866520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70134284271320
24
+ version_requirements: *17866520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rr
27
- requirement: &70134284270880 !ruby/object:Gem::Requirement
27
+ requirement: &17866000 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,18 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70134284270880
35
+ version_requirements: *17866000
36
+ - !ruby/object:Gem::Dependency
37
+ name: timecop
38
+ requirement: &17865580 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *17865580
36
47
  description: Yell - Your Extensible Logging Library. Define multiple adapters, various
37
48
  log level combinations or message formatting options like you've never done before
38
49
  email:
@@ -54,6 +65,7 @@ files:
54
65
  - examples/003.2-formatting-BasicFormat.rb
55
66
  - examples/003.3-formatting-ExtendedFormat.rb
56
67
  - examples/003.4-formatting-on-your-own.rb
68
+ - examples/004.1-colorizing-the-log-output.rb
57
69
  - lib/yell.rb
58
70
  - lib/yell/adapters.rb
59
71
  - lib/yell/adapters/base.rb
@@ -68,6 +80,10 @@ files:
68
80
  - lib/yell/version.rb
69
81
  - spec/spec_helper.rb
70
82
  - spec/yell/adapters/base_spec.rb
83
+ - spec/yell/adapters/datefile_spec.rb
84
+ - spec/yell/adapters/file_spec.rb
85
+ - spec/yell/adapters/io_spec.rb
86
+ - spec/yell/adapters/streams_spec.rb
71
87
  - spec/yell/adapters_spec.rb
72
88
  - spec/yell/event_spec.rb
73
89
  - spec/yell/formatter_spec.rb
@@ -95,17 +111,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
111
  version: '0'
96
112
  requirements: []
97
113
  rubyforge_project: yell
98
- rubygems_version: 1.8.17
114
+ rubygems_version: 1.8.10
99
115
  signing_key:
100
116
  specification_version: 3
101
117
  summary: Yell - Your Extensible Logging Library
102
- test_files:
103
- - spec/spec_helper.rb
104
- - spec/yell/adapters/base_spec.rb
105
- - spec/yell/adapters_spec.rb
106
- - spec/yell/event_spec.rb
107
- - spec/yell/formatter_spec.rb
108
- - spec/yell/level_spec.rb
109
- - spec/yell/logger_spec.rb
110
- - spec/yell_spec.rb
118
+ test_files: []
111
119
  has_rdoc: