Permalink
Browse files

massive reorg...specs are green but still a WIP

  • Loading branch information...
1 parent 14c9683 commit 23f0057579da55eb56108259967981eaddcf0585 @rsanheim rsanheim committed Nov 16, 2008
Showing with 262 additions and 207 deletions.
  1. +3 −5 Rakefile
  2. +1 −1 init.rb
  3. +30 −95 lib/log_buddy.rb
  4. +78 −0 lib/log_buddy/log.rb
  5. +9 −0 lib/log_buddy/version.rb
  6. +1 −0 spec/helper.rb
  7. +15 −106 spec/log_buddy_spec.rb
  8. +125 −0 spec/log_spec.rb
View
8 Rakefile
@@ -1,10 +1,10 @@
require 'rubygems'
gem 'echoe'
require 'echoe'
-require './lib/log_buddy.rb'
require 'spec/rake/spectask'
+require File.join(File.dirname(__FILE__), *%w[lib log_buddy version])
-echoe = Echoe.new('log_buddy', LogBuddy::VERSION) do |p|
+echoe = Echoe.new('log_buddy', LogBuddy::VERSION::STRING) do |p|
p.rubyforge_name = 'thinkrelevance'
p.author = 'Rob Sanheim - Relevance'
p.email = 'opensource@thinkrelevance.com'
@@ -20,9 +20,7 @@ Rake.application.instance_variable_get(:@tasks).delete("default")
Rake.application.instance_variable_get(:@tasks).delete("test")
desc "Run examples"
-Spec::Rake::SpecTask.new("spec") do |t|
- t.spec_files = FileList['spec/**/*_spec.rb']
-end
+Spec::Rake::SpecTask.new
task :default => :spec
View
2 init.rb
@@ -1,2 +1,2 @@
-require 'log_buddy'
+require File.join(File.dirname(__FILE__), *%w[lib log_buddy])
LogBuddy.init unless ENV["SAFE_LOG_BUDDY"]
View
125 lib/log_buddy.rb
@@ -1,112 +1,47 @@
-=begin rdoc
-LogBuddy is a developer tool for easy logging while testing, debugging, and inspecting.
-
-Log shortcut method to give you easy, concise output of variables with their names and values.
-
-Examples:
- a = "foo"
- @a = "my var"
- def bark
- "woof!"
- end
-
- d { a } # logs "a = 'foo'"
- d { @a } # logs "@a = 'my var'"
- d { bark } # logs "bark = woof!"
-
-=end
-class LogBuddy
- VERSION = '0.1.3'
-
- # Use LogBuddy!
+module LogBuddy
+ # Configure and include LogBuddy into Object.
+ # You can pass in any of the following configuration options:
+ #
+ # * <tt>:logger</tt> - the logger instance that LogBuddy should use (if not provided,
+ # tries to default to RAILS_DEFAULT_LOGGER, and then to a STDOUT logger).
+ # * <tt):stdout</tt> - whether LogBuddy should _also_ log to STDOUT, very helpful for Autotest (default is +true+).
def self.init(options = {})
- @logger = options[:default_logger]
+ @logger = options[:logger]
+ @log_to_stdout = options.has_key?(:log_to_stdout) ? options[:log_to_stdout] : true
mixin_to_object
end
-
+
# Add the LogBuddy::Mixin to Object instance and class level.
def self.mixin_to_object
Object.class_eval {
include LogBuddy::Mixin
extend LogBuddy::Mixin
}
end
-
- # The main Mixin that gets added on the #init call
- module Mixin
- # This is where the magic happens. This method can take a plain old string, and it will log
- # it like any call to Logger#debug. To get the name of the thing you are logging and its value,
- # use the block form:
- # d { @a }
- #
- # Seperate with semicolons for multiple things - pretty much any valid ruby will work.
- # d { @@foo; MY_CONST }
- # d { @person; @@place; object.method() }
- #
- def d(msg = nil, &blk)
- LogBuddy.debug(msg) if msg
- return unless block_given?
- begin
- logged_line = LogBuddy.read_line(caller[0])
- arguments = LogBuddy.parse_args(logged_line)
- arguments.each do |arg|
- result = eval(arg, blk.binding)
- LogBuddy.debug(%[#{arg} = '#{result}'\n])
- end
- rescue RuntimeError => e
- LogBuddy.debug "LogBuddy caught an exception: #{e.message}"
- end
- end
- # Add a default logger to everything, everywhere.
+ class << self
def logger
- LogBuddy.default_logger
+ return @logger if @logger
+ @logger = init_default_logger
end
- end
-
- private
-
- # Default logger LogBuddy will use
- def self.default_logger
- return @logger if @logger
- @logger = init_default_logger
- end
-
- # Attempt to establish a default logger - first try RAILS_DEFAULT_LOGGER,
- # then fallback to default.
- def self.init_default_logger
- if Object.const_defined?("RAILS_DEFAULT_LOGGER")
- @logger = Object.const_get("RAILS_DEFAULT_LOGGER")
- else
- require 'logger'
- @logger = Logger.new(STDOUT)
+
+ def log_to_stdout?
+ @log_to_stdout
+ end
+
+ private
+
+ def init_default_logger
+ if Object.const_defined?("RAILS_DEFAULT_LOGGER")
+ @logger = Object.const_get("RAILS_DEFAULT_LOGGER")
+ else
+ require 'logger'
+ @logger = Logger.new(STDOUT)
+ end
end
- end
-
- # Just debug it
- def self.debug(str)
- stdout_puts(str)
- default_logger.debug(str)
- end
-
- def self.stdout_puts(str)
- puts str
- end
-
- # Returns array of arguments in the block
- # You must ues the brace form (ie d { "hi" }) and not do...end
- def self.parse_args(logged_line)
- block_contents = logged_line[/\{(.*)\}/, 1]
- args = block_contents.split(";").map {|arg| arg.strip }
- end
-
- # Return the calling line
- def self.read_line(frame)
- file, line_number = frame.split(/:/, 2)
- line_number = line_number.to_i
- lines = File.readlines(file)
- lines[line_number - 1]
end
-
end
+
+require File.join(File.dirname(__FILE__), *%w[log_buddy log])
+require File.join(File.dirname(__FILE__), *%w[log_buddy version])
View
78 lib/log_buddy/log.rb
@@ -0,0 +1,78 @@
+=begin rdoc
+LogBuddy is a developer tool for easy logging while testing, debugging, and inspecting.
+
+Log shortcut method to give you easy, concise output of variables with their names and values.
+
+Examples:
+ a = "foo"
+ @a = "my var"
+ def bark
+ "woof!"
+ end
+
+ d { a } # logs "a = 'foo'"
+ d { @a } # logs "@a = 'my var'"
+ d { bark } # logs "bark = woof!"
+
+=end
+module LogBuddy
+
+ # The main Mixin that gets added on the #init call
+ module Mixin
+ # This is where the magic happens. This method can take a plain old string, and it will log
+ # it like any call to Logger#debug. To get the name of the thing you are logging and its value,
+ # use the block form:
+ # d { @a }
+ #
+ # Seperate with semicolons for multiple things - pretty much any valid ruby will work.
+ # d { @@foo; MY_CONST }
+ # d { @person; @@place; object.method() }
+ #
+ def d(msg = nil, &blk)
+ LogBuddy.debug(msg) if msg
+ return unless block_given?
+ begin
+ logged_line = LogBuddy.read_line(caller[0])
+ arguments = LogBuddy.parse_args(logged_line)
+ arguments.each do |arg|
+ result = eval(arg, blk.binding)
+ LogBuddy.debug(%[#{arg} = '#{result}'\n])
+ end
+ rescue RuntimeError => e
+ LogBuddy.debug "LogBuddy caught an exception: #{e.message}"
+ end
+ end
+
+ def logger
+ LogBuddy.logger
+ end
+ end
+
+ private
+
+ # Just debug it
+ def self.debug(str)
+ stdout_puts(str) if @stdout
+ logger.debug(str)
+ end
+
+ def self.stdout_puts(str)
+ puts str
+ end
+
+ # Returns array of arguments in the block
+ # You must ues the brace form (ie d { "hi" }) and not do...end
+ def self.parse_args(logged_line)
+ block_contents = logged_line[/\{(.*)\}/, 1]
+ args = block_contents.split(";").map {|arg| arg.strip }
+ end
+
+ # Return the calling line
+ def self.read_line(frame)
+ file, line_number = frame.split(/:/, 2)
+ line_number = line_number.to_i
+ lines = File.readlines(file)
+
+ lines[line_number - 1]
+ end
+end
View
9 lib/log_buddy/version.rb
@@ -0,0 +1,9 @@
+module LogBuddy
+ module VERSION #:nodoc:
+ MAJOR = 0
+ MINOR = 0
+ TINY = 2
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ end
+end
View
1 spec/helper.rb
@@ -1,3 +1,4 @@
+require 'logger'
require 'rubygems'
gem 'rspec'
gem 'mocha'
View
121 spec/log_buddy_spec.rb
@@ -1,128 +1,37 @@
require File.expand_path(File.join(File.dirname(__FILE__), *%w[helper]))
-module SomeModule
- def self.say_something(name)
- "#{message} #{name}"
- end
+describe LogBuddy do
- def self.message
- "hello"
+ it "has logger" do
+ LogBuddy.should respond_to :logger
end
- def self.raise_runtime_error
- raise RuntimeError
+ it "has stdout config option" do
+ LogBuddy.should respond_to :log_to_stdout?
end
-end
-
-describe LogBuddy, " contract" do
- describe "object extensions" do
+
+ describe "init" do
it "mixes itself into Object instance and class level by default" do
Object.expects(:include).with(LogBuddy::Mixin)
Object.expects(:extend).with(LogBuddy::Mixin)
LogBuddy.init
end
-
+
it "adds logger method to Object instance and class" do
LogBuddy.init
Object.new.should respond_to :logger
Object.should respond_to :logger
end
- it "uses RAILS_DEFAULT_LOGGER if its defined" do
- begin
- Object.const_set "RAILS_DEFAULT_LOGGER", stub_everything
- LogBuddy.init
- Object.logger.should == RAILS_DEFAULT_LOGGER
- ensure
- Object.send :remove_const, "RAILS_DEFAULT_LOGGER"
- end
- end
-
- it "uses a plain STDOUT Ruby logger if there is no RAILS_DEFAULT_LOGGER" do
+ it "defaults to log to stdout (as well as logger)" do
LogBuddy.init
- Object.logger.should == LogBuddy.default_logger
- end
-
- it "can override the default logger" do
- file_logger = Logger.new "test.log"
- LogBuddy.init :default_logger => file_logger
- Object.logger.should == file_logger
- end
- end
-
- describe "outputting the code being logged and its result" do
- before { LogBuddy.init }
- it "should log to default logger" do
- LogBuddy.expects(:default_logger).returns(logger = mock)
- logger.expects(:debug).with(anything)
- d {'hi'}
- end
-
- it "should log a plain arg" do
- LogBuddy.expects(:debug).with('hi')
- d 'hi'
- end
-
- it "logs both if given an arg and a block" do
- LogBuddy.expects(:debug).with('hi mom')
- LogBuddy.expects(:debug).with(%[foo = 'foo'\n])
- foo = "foo"
- d("hi mom") { foo }
- end
-
- it "does nothing without a block" do
- lambda { d }.should_not raise_error
- end
-
- it "should output only local vars in the block" do
- LogBuddy.expects(:debug).with(%[a = 'foo'\n])
- b = "bad"
- a = "foo"
- d { a }
- end
-
- it "should output instance vars" do
- LogBuddy.expects(:debug).with(%[@a = 'foo'\n])
- @a = "foo"
- d { @a }
- end
-
- it "should output constants" do
- FOO_CONST = "yo!"
- LogBuddy.expects(:debug).with(%[FOO_CONST = 'yo!'\n])
- d { FOO_CONST }
- end
-
- it "should output class vars" do
- LogBuddy.expects(:debug).with(%[@@class_var = 'hi'\n])
- @@class_var = "hi"
- d { @@class_var }
+ LogBuddy.log_to_stdout?.should == true
end
-
- it "should output method calls" do
- LogBuddy.expects(:debug).with(%[SomeModule.say_something("dude!!!!") = 'hello dude!!!!'\n])
- d { SomeModule.say_something("dude!!!!") }
- end
-
- it "should output multiple things with each having their own log calls" do
- local1 = '1'
- local2 = '2'
- @ivar1 = '1'
- LogBuddy.expects(:debug).with(%[local1 = '1'\n])
- LogBuddy.expects(:debug).with(%[local2 = '2'\n])
- LogBuddy.expects(:debug).with(%[@ivar1 = '1'\n])
- d { local1; local2; @ivar1 }
- end
-
- it "should gracefully handle runtimer errors" do
- LogBuddy.expects(:debug).with('LogBuddy caught an exception: RuntimeError')
- d { SomeModule.raise_runtime_error }
- end
-
- it "logs to stdout as well as the default logger" do
- pending("failing in rspec for some reason - no idea why")
- LogBuddy.expects(:stdout_puts).with(anything) #.with(%["foo" = 'foo'\n])
- d { "foo" }
+
+ it "can be configured to log to stdout" do
+ LogBuddy.init :stdout => false
+ LogBuddy.log_to_stdout?.should == true
end
end
+
end
View
125 spec/log_spec.rb
@@ -0,0 +1,125 @@
+require File.expand_path(File.join(File.dirname(__FILE__), *%w[helper]))
+
+module SomeModule
+ def self.say_something(name)
+ "#{message} #{name}"
+ end
+
+ def self.message
+ "hello"
+ end
+
+ def self.raise_runtime_error
+ raise RuntimeError
+ end
+end
+
+describe LogBuddy::Mixin, " behavior" do
+
+ it "uses RAILS_DEFAULT_LOGGER if its defined" do
+ begin
+ Object.const_set "RAILS_DEFAULT_LOGGER", stub_everything
+ LogBuddy.init
+ Object.logger.should == RAILS_DEFAULT_LOGGER
+ ensure
+ Object.send :remove_const, "RAILS_DEFAULT_LOGGER"
+ end
+ end
+
+ it "uses a plain STDOUT Ruby logger if there is no RAILS_DEFAULT_LOGGER" do
+ LogBuddy.init
+ Object.logger.should == LogBuddy.logger
+ end
+
+ it "can override the default logger" do
+ file_logger = Logger.new "test.log"
+ LogBuddy.init :logger => file_logger
+ Object.logger.should == file_logger
+ end
+
+ describe "outputting the code being logged and its result" do
+ before { LogBuddy.init }
+ it "should log to default logger" do
+ LogBuddy.expects(:logger).returns(logger = mock)
+ logger.expects(:debug).with(anything)
+ d {'hi'}
+ end
+
+ it "should log a plain arg" do
+ LogBuddy.expects(:debug).with('hi')
+ d 'hi'
+ end
+
+ it "logs both if given an arg and a block" do
+ LogBuddy.expects(:debug).with('hi mom')
+ LogBuddy.expects(:debug).with(%[foo = 'foo'\n])
+ foo = "foo"
+ d("hi mom") { foo }
+ end
+
+ it "does nothing without a block" do
+ lambda { d }.should_not raise_error
+ end
+
+ it "should output only local vars in the block" do
+ LogBuddy.expects(:debug).with(%[a = 'foo'\n])
+ b = "bad"
+ a = "foo"
+ d { a }
+ end
+
+ it "should output instance vars" do
+ LogBuddy.expects(:debug).with(%[@a = 'foo'\n])
+ @a = "foo"
+ d { @a }
+ end
+
+ it "should output constants" do
+ FOO_CONST = "yo!"
+ LogBuddy.expects(:debug).with(%[FOO_CONST = 'yo!'\n])
+ d { FOO_CONST }
+ end
+
+ it "should output class vars" do
+ LogBuddy.expects(:debug).with(%[@@class_var = 'hi'\n])
+ @@class_var = "hi"
+ d { @@class_var }
+ end
+
+ it "should output method calls" do
+ LogBuddy.expects(:debug).with(%[SomeModule.say_something("dude!!!!") = 'hello dude!!!!'\n])
+ d { SomeModule.say_something("dude!!!!") }
+ end
+
+ it "should output multiple things with each having their own log calls" do
+ local1 = '1'
+ local2 = '2'
+ @ivar1 = '1'
+ LogBuddy.expects(:debug).with(%[local1 = '1'\n])
+ LogBuddy.expects(:debug).with(%[local2 = '2'\n])
+ LogBuddy.expects(:debug).with(%[@ivar1 = '1'\n])
+ d { local1; local2; @ivar1 }
+ end
+
+ it "should gracefully handle runtimer errors" do
+ LogBuddy.expects(:debug).with('LogBuddy caught an exception: RuntimeError')
+ d { SomeModule.raise_runtime_error }
+ end
+
+ end
+
+ describe "stdout" do
+ it "logs to stdout as well as the default logger" do
+ LogBuddy.init :stdout => true
+ pending("failing in rspec for some reason - no idea why")
+ LogBuddy.expects(:stdout_puts).with(anything) #.with(%["foo" = 'foo'\n])
+ d { "foo" }
+ end
+
+ it "doesnt log to stdout if stdout configured off" do
+ LogBuddy.init :stdout => false
+ LogBuddy.expects(:stdout_puts).never #.with(%["foo" = 'foo'\n])
+ d { "foo" }
+ end
+ end
+end

0 comments on commit 23f0057

Please sign in to comment.