├── .rvmrc ├── Gemfile ├── .travis.yml ├── .gitignore ├── init.rb ├── lib ├── log_buddy │ ├── version.rb │ ├── mixin.rb │ └── utils.rb └── log_buddy.rb ├── spec └── log_buddy │ ├── spec_helper.rb │ ├── log_buddy_init_spec.rb │ ├── log_buddy_spec.rb │ └── log_spec.rb ├── examples.rb ├── Rakefile ├── log_buddy.gemspec ├── LICENSE ├── CHANGELOG └── README.markdown /.rvmrc: -------------------------------------------------------------------------------- 1 | rvm use ruby-1.9.2 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.8.7 3 | - 1.9.2 4 | - 1.9.3 5 | - jruby 6 | script: bundle exec rspec spec 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .tm_last_run_ruby 2 | *.log 3 | doc/* 4 | pkg/* 5 | coverage 6 | TAGS 7 | coverage/ 8 | Gemfile.lock 9 | -------------------------------------------------------------------------------- /init.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), *%w[lib log_buddy]) 2 | LogBuddy.init unless ENV["SAFE_LOG_BUDDY"] -------------------------------------------------------------------------------- /lib/log_buddy/version.rb: -------------------------------------------------------------------------------- 1 | module LogBuddy 2 | module Version #:nodoc: 3 | MAJOR = 0 4 | MINOR = 7 5 | TINY = 0 6 | 7 | STRING = [MAJOR, MINOR, TINY].join('.') 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/log_buddy/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "logger" 2 | require "rspec" 3 | require "mocha" 4 | require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "log_buddy")) 5 | 6 | def silence_warnings 7 | old_verbose, $VERBOSE = $VERBOSE, nil 8 | yield 9 | ensure 10 | $VERBOSE = old_verbose 11 | end 12 | 13 | RSpec.configure do |config| 14 | config.filter_run :focused => true 15 | config.run_all_when_everything_filtered = true 16 | config.color_enabled = true 17 | config.alias_example_to :fit, :focused => true 18 | config.formatter = :documentation 19 | config.mock_with :mocha 20 | end 21 | -------------------------------------------------------------------------------- /examples.rb: -------------------------------------------------------------------------------- 1 | require 'lib/log_buddy' 2 | LogBuddy.init 3 | 4 | a = "foo" 5 | @a = "my var" 6 | @@bar = "class var!" 7 | def bark 8 | "woof!" 9 | end 10 | 11 | module Foo; 12 | def self.module_method 13 | "hi!!" 14 | end 15 | end 16 | 17 | 18 | # LogBuddy calls and their output: 19 | 20 | d "hi" # hi 21 | d { a } # a = "foo" 22 | d { @a } # @a = "my var" 23 | d { @@bar } # @@bar = "class var!" 24 | d { bark } # bark = "woof!" 25 | d { Foo::module_method } # Foo::module_method = "hi!!" 26 | 27 | hsh = {:foo => "bar", "key" => "value"} 28 | array = [1,2,3,4,"5"] 29 | 30 | d { hsh } 31 | d { array } -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | 3 | begin 4 | require 'rspec/core/rake_task' 5 | 6 | RSpec::Core::RakeTask.new(:spec) 7 | 8 | RSpec::Core::RakeTask.new(:coverage) do |spec| 9 | spec.pattern = 'spec/**/*_spec.rb' 10 | spec.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,/Library/Ruby/*,config/*" --text-summary --sort coverage] 11 | spec.rcov = true 12 | end 13 | 14 | require "yaml" 15 | RubyVersions = YAML.load_file(".travis.yml")["rvm"] 16 | desc "Run Rspec against multiple Rubies: #{RubyVersions.join(", ")}" 17 | task :spec_all do 18 | cmd = %[bash -c 'source ~/.rvm/scripts/rvm; rvm #{RubyVersions.join(",")} do rake spec'] 19 | puts cmd 20 | system cmd 21 | end 22 | 23 | 24 | if RUBY_VERSION <= "1.8.7" 25 | task :default => [:coverage] 26 | else 27 | task :default => [:spec] 28 | end 29 | rescue LoadError => e 30 | puts "Rspec not available to run tests. Install it with: gem install rspec --pre" 31 | puts e 32 | puts e.backtrace 33 | end 34 | -------------------------------------------------------------------------------- /log_buddy.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path('../lib/log_buddy/version', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ["Rob Sanheim"] 6 | gem.email = ["rsanheim@gmail.com"] 7 | gem.description = %q{Log statements along with their name easily. Mixin a logger everywhere when you need it.} 8 | gem.summary = %q{Log Buddy is your little development buddy.} 9 | gem.homepage = %q{http://github.com/relevance/log_buddy} 10 | 11 | gem.files = `git ls-files`.split($\) 12 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 13 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 14 | gem.name = "log_buddy" 15 | gem.version = LogBuddy::Version::STRING 16 | gem.add_development_dependency 'rspec', "~> 2.8" 17 | gem.add_development_dependency 'mocha', "~> 0.9" 18 | gem.add_development_dependency "rake", "~> 0.9.2" 19 | gem.add_development_dependency 'bundler', '~> 1.1' 20 | end 21 | -------------------------------------------------------------------------------- /lib/log_buddy/mixin.rb: -------------------------------------------------------------------------------- 1 | module LogBuddy 2 | # The main Mixin that gets added on the #init call 3 | module Mixin 4 | # This is where the magic happens. This method can take a plain old string, and it will log 5 | # it like any call to Logger#debug. To get the name of the thing you are logging and its value, 6 | # use the block form: 7 | # d { @a } 8 | # 9 | # Seperate with semicolons for multiple things - pretty much any valid ruby will work. 10 | # d { @@foo; MY_CONST } 11 | # d { @person; @@place; object.method() } 12 | # 13 | def d(msg = nil, &blk) 14 | LogBuddy.debug(msg) if msg 15 | return unless block_given? 16 | begin 17 | logged_line = LogBuddy.read_line(caller[0]) 18 | arguments = LogBuddy.parse_args(logged_line) 19 | arguments.each do |arg| 20 | LogBuddy.arg_and_blk_debug(arg, blk) 21 | end 22 | rescue => e 23 | LogBuddy.debug "LogBuddy caught an exception: #{e.message}" 24 | end 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /spec/log_buddy/log_buddy_init_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.join(File.dirname(__FILE__), *%w[spec_helper])) 2 | 3 | describe LogBuddy do 4 | describe "init" do 5 | after { reset_safe_log_buddy_mode } 6 | 7 | it "doesnt mixin to object if SAFE_LOG_BUDDY is true" do 8 | LogBuddy.expects(:init).never 9 | ENV["SAFE_LOG_BUDDY"] = "true" 10 | load_init 11 | end 12 | 13 | it "mixin to object if SAFE_LOG_BUDDY is true" do 14 | LogBuddy.expects(:init).once 15 | load_init 16 | end 17 | 18 | def load_init 19 | silence_warnings do 20 | load File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. init.rb])) 21 | end 22 | end 23 | 24 | def reset_safe_log_buddy_mode 25 | ENV["SAFE_LOG_BUDDY"] = nil 26 | end 27 | 28 | it "should be disabled when the :disabled key is true" do 29 | LogBuddy.init(:disabled => true) 30 | fake_logger = mock('logger') 31 | LogBuddy.stubs(:logger).returns(fake_logger) 32 | fake_logger.expects(:debug).never 33 | d { "Hello, World!" } 34 | end 35 | end 36 | 37 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 Relevance, Inc. - http://thinkrelevance.com 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 NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /spec/log_buddy/log_buddy_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.join(File.dirname(__FILE__), *%w[spec_helper])) 2 | 3 | describe LogBuddy do 4 | 5 | it "has logger" do 6 | LogBuddy.should respond_to(:logger) 7 | end 8 | 9 | it "has stdout config option" do 10 | LogBuddy.should respond_to(:log_to_stdout?) 11 | end 12 | 13 | it "can override the default logger" do 14 | file_logger = Logger.new "test.log" 15 | LogBuddy.init :logger => file_logger 16 | LogBuddy.logger.should == file_logger 17 | end 18 | 19 | describe "init" do 20 | it "defaults to log to stdout (as well as logger)" do 21 | LogBuddy.init 22 | LogBuddy.log_to_stdout?.should == true 23 | end 24 | 25 | it "can be configured to log to stdout" do 26 | LogBuddy.init :stdout => false 27 | LogBuddy.log_to_stdout?.should == true 28 | end 29 | 30 | it "defaults to not using awesome_print for object inspection" do 31 | LogBuddy.init 32 | LogBuddy.use_awesome_print?.should == false 33 | end 34 | 35 | it "can be configured to use awesome_print for object inspection" do 36 | LogBuddy.init :use_awesome_print => true 37 | LogBuddy.use_awesome_print?.should == true 38 | end 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /lib/log_buddy/utils.rb: -------------------------------------------------------------------------------- 1 | module LogBuddy 2 | module Utils 3 | 4 | def debug(obj) 5 | return if @disabled 6 | str = obj_to_string(obj) 7 | stdout_puts(str) if log_to_stdout? 8 | logger.debug(str) 9 | end 10 | 11 | def arg_and_blk_debug(arg, blk) 12 | result = eval(arg, blk.binding) 13 | result_str = obj_to_string(result, :quote_strings => true) 14 | LogBuddy.debug(%[#{arg} = #{result_str}\n]) 15 | end 16 | 17 | def stdout_puts(str) 18 | puts str 19 | end 20 | 21 | # Returns array of arguments in the block 22 | # You must use the brace form (ie d { "hi" }) and not do...end 23 | def parse_args(logged_line) 24 | block_contents = logged_line[/\{(.*?)\}/, 1] 25 | args = block_contents ? block_contents.split(";").map {|arg| arg.strip } : [] 26 | end 27 | 28 | # Return the calling line 29 | def read_line(frame) 30 | file, line_number = frame.split(/:/, 2) 31 | line_number = line_number.to_i 32 | lines = File.readlines(file) 33 | 34 | lines[line_number - 1] 35 | end 36 | 37 | def obj_to_string(obj, options = {}) 38 | quote_strings = options.delete(:quote_strings) 39 | case obj 40 | when ::String 41 | quote_strings ? %["#{obj}"] : obj 42 | when ::Exception 43 | "#{ obj.message } (#{ obj.class })\n" << 44 | (obj.backtrace || []).join("\n") 45 | else 46 | LogBuddy.use_awesome_print? && obj.respond_to?(:ai) ? 47 | obj.ai : obj.inspect 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | v0.7.0 2 | * Add use_awesome_print option for logging 3 | * Fix warning from #split called on nil 4 | * Put tests on travis 5 | * Clean up Rakefile and gemspec 6 | 7 | v0.6.0 Use Rails.logger if available - avoid deprecation warnings in Rails 3+ 8 | 9 | v0.5.1 init automatically unless SAFE_LOG_BUDDY (in ENV) is set 10 | 11 | v0.5.0 Overall cleanup and making things safer: 12 | - move to Rspec2 13 | - move Version into the code base as a constant and out of yml 14 | - remove GemLoger 15 | - don't mixin in a logger method to Object, ever -- too dangerous. 16 | - fix issue where logged line goes away and raises exception (GH-2) 17 | 18 | v0.4.10 Switch to jeweler; remove dependencies that were superfluous 19 | 20 | v0.4.9 Added gem logging for debugging help when tracking down Gem activation errors 21 | 22 | v0.2.3 Updating Micronaut 23 | 24 | v0.2.0. Better log output of objects based on their type, very similar to Logger/irb behavior; update to micronaut 0.1.0 25 | 26 | v0.1.5. Clean up specs and remove noise from spec run 27 | 28 | v0.1.4. Micronauts Unite! Test Suite now runs via Micronaut - http://github.com/spicycode/micronaut/ 29 | 30 | v0.1.3. Use plain old echoe; really fix rubygems errors (I hope) 31 | 32 | v0.1.2. Attempting to fix rubygems errors 33 | 34 | v0.1.1. Handle exceptions from within the block 35 | 36 | v0.1.0. Specify, clean up 37 | 38 | v0.0.6. changed to mixing to Object by default - set ENV["SAFE_LOG_BUDDY"] = true to override 39 | 40 | v0.0.5. update echoe dependency to work with github 41 | 42 | v0.0.4. add dev dependencies, remove gem calls from rdoc task 43 | 44 | v0.0.3. specs and tweaks 45 | 46 | v0.0.2. rdocs; support for multiple statements in one "d" call separated by semicolons 47 | 48 | v0.0.1. Initial release to github; Birthday 49 | -------------------------------------------------------------------------------- /lib/log_buddy.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), *%w[log_buddy utils]) 2 | require File.join(File.dirname(__FILE__), *%w[log_buddy mixin]) 3 | require File.join(File.dirname(__FILE__), *%w[log_buddy version]) 4 | 5 | =begin rdoc 6 | LogBuddy is a developer tool for easy logging while testing, debugging, and inspecting. 7 | 8 | The d log method to give you easy, concise output of variables with their names and values. 9 | 10 | Requiring 'log_buddy' will _automatically_ mixin the d method into Object. You can avoid this 11 | behavior by setting SAFE_LOG_BUDDY to true in your environment before requiring LogBuddy. 12 | 13 | Examples: 14 | a = "foo" 15 | @a = "my var" 16 | def bark 17 | "woof!" 18 | end 19 | 20 | d { a } # logs "a = 'foo'" 21 | d { @a } # logs "@a = 'my var'" 22 | d { bark } # logs "bark = woof!" 23 | 24 | =end 25 | module LogBuddy 26 | # Configure and include LogBuddy into Object. 27 | # You can pass in any of the following configuration options: 28 | # 29 | # * :logger - the logger instance that LogBuddy should use (if not provided, 30 | # tries to default to RAILS_DEFAULT_LOGGER, and then to a STDOUT logger). 31 | # * :log_to_stdout - whether LogBuddy should _also_ log to STDOUT, very helpful for Autotest (default is +true+). 32 | # * :disabled - when true, LogBuddy will not produce any output 33 | # * :use_awesome_print - when true, LogBuddy will log object with awesome_print 34 | def self.init(options = {}) 35 | @logger = options[:logger] 36 | @log_to_stdout = options.has_key?(:log_to_stdout) ? options[:log_to_stdout] : true 37 | @use_awesome_print = options.has_key?(:use_awesome_print) ? options[:use_awesome_print] : false 38 | @disabled = (options[:disabled] == true) 39 | mixin_to_object 40 | end 41 | 42 | # Add the LogBuddy::Mixin to Object instance and class level. 43 | def self.mixin_to_object 44 | Object.class_eval { 45 | include LogBuddy::Mixin 46 | extend LogBuddy::Mixin 47 | } 48 | end 49 | 50 | class << self 51 | include LogBuddy::Utils 52 | def logger 53 | return @logger if @logger 54 | @logger = init_default_logger 55 | end 56 | 57 | def log_to_stdout? 58 | @log_to_stdout 59 | end 60 | 61 | def use_awesome_print? 62 | @use_awesome_print 63 | end 64 | 65 | private 66 | 67 | # First try Rails.logger, then RAILS_DEFAULT_LOGGER (for older 68 | # versions of Rails), then just use a STDOUT Logger 69 | def init_default_logger 70 | @logger = if rails_environment && rails_environment.respond_to?(:logger) 71 | rails_environment.logger 72 | elsif Object.const_defined?("RAILS_DEFAULT_LOGGER") 73 | Object.const_get("RAILS_DEFAULT_LOGGER") 74 | else 75 | require 'logger' 76 | Logger.new(STDOUT) 77 | end 78 | end 79 | 80 | def rails_environment 81 | Object.const_defined?("Rails") && Object.const_get("Rails") 82 | end 83 | 84 | end 85 | 86 | init unless ENV["SAFE_LOG_BUDDY"] 87 | end 88 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # LogBuddy 2 | 3 | ## DESCRIPTION 4 | 5 | log_buddy is your friendly little log buddy at your side, helping you dev, debug, and test. 6 | 7 | [![Build Status](https://secure.travis-ci.org/relevance/log_buddy.png?branch=master)](http://travis-ci.org/relevance/log_buddy) 8 | 9 | ## SYNOPSIS 10 | 11 | Require the init.rb file to use log_buddy. By default, it will add two methods to every object at the instance and class level: "d" and "logger". To use log_buddy without the automatic object intrusion, set ENV["SAFE_LOG_BUDDY"] = true before requiring the init.rb. 12 | 13 | You can use your own logger with LogBuddy by passing it into init's options hash: 14 | 15 | LogBuddy.init :logger => Logger.new('my_log.log') 16 | 17 | Now you have your logger available from any object, at the instance level and class level: 18 | 19 | obj = Object.new 20 | obj.logger.debug("hi") # logs to 'my_log.log' 21 | class MyClass; end 22 | MyClass.logger.info("heya") # also logs to 'my_log.log' 23 | 24 | You also have a method called "d" (for "debug") on any object, which is used for quick debugging and logging of things while you are developing. 25 | Its especially useful while using autotest. When you call the "d" method with an inline block, it will log the name of the things 26 | in the block and the result. Examples: 27 | 28 | a = "foo" 29 | @a = "my var" 30 | @@bar = "class var! 31 | def bark 32 | "woof!" 33 | end 34 | 35 | d { a } # logs "a = 'foo'" 36 | d { @a } # logs "@a = 'my var'" 37 | d { @@bar } # logs "@@bar = 'class var!'" 38 | d { bark } # logs "bark = woof!" 39 | 40 | 41 | See examples.rb for live examples you can run. 42 | 43 | When you occasionally want to disable LogBuddy (but you don't want to have to remove all your debug statements), you can pass the :disabled option into init's options hash: 44 | 45 | LogBuddy.init :disabled => true 46 | 47 | ## REQUIREMENTS 48 | 49 | * Ruby 1.8.7 and greater or JRuby 50 | 51 | ## ISSUES 52 | 53 | * This is meant for non-production use while developing and testing --> it does stuff that is slow and you probably don't want happening in your production environment. 54 | * Don't even try using this in irb. 55 | 56 | ## INSTALL 57 | 58 | gem install log_buddy 59 | 60 | ## URLS 61 | 62 | * File Issues: http://github.com/relevance/log_buddy/issues 63 | * View Source: http://github.com/relevance/log_buddy 64 | * Git clone Source: git://github.com/relevance/log_buddy.git 65 | * Documentation: http://rdoc.info/gems/log_buddy 66 | 67 | ## LICENSE 68 | 69 | (The MIT License) 70 | 71 | Copyright (c) 2009 Relevance, Inc. - http://thinkrelevance.com 72 | 73 | Permission is hereby granted, free of charge, to any person obtaining 74 | a copy of this software and associated documentation files (the 75 | 'Software'), to deal in the Software without restriction, including 76 | without limitation the rights to use, copy, modify, merge, publish, 77 | distribute, sublicense, and/or sell copies of the Software, and to 78 | permit persons to whom the Software is furnished to do so, subject to 79 | the following conditions: 80 | 81 | The above copyright notice and this permission notice shall be 82 | included in all copies or substantial portions of the Software. 83 | 84 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 87 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 88 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 89 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 90 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 91 | -------------------------------------------------------------------------------- /spec/log_buddy/log_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.join(File.dirname(__FILE__), *%w[spec_helper])) 2 | 3 | module SomeModule 4 | def self.say_something(name) 5 | "#{message} #{name}" 6 | end 7 | 8 | def self.message 9 | "hello" 10 | end 11 | 12 | def self.raise_runtime_error 13 | raise RuntimeError 14 | end 15 | end 16 | 17 | describe LogBuddy::Mixin, " behavior" do 18 | 19 | describe "init" do 20 | context "Rails environment" do 21 | it "uses Rails.logger first" do 22 | begin 23 | rails_logger = stub_everything 24 | rails_const = mock("Rails const with logger", :logger => rails_logger) 25 | Object.const_set "Rails", rails_const 26 | LogBuddy.init 27 | LogBuddy.logger.should == rails_logger 28 | ensure 29 | Object.send :remove_const, "Rails" 30 | end 31 | end 32 | 33 | it "falls back to RAILS_DEFAULT_LOGGER if necessary" do 34 | begin 35 | rails_default_logger = stub_everything 36 | rails_const = stub("Rails const without logger") 37 | Object.const_set "Rails", rails_const 38 | Object.const_set "RAILS_DEFAULT_LOGGER", rails_default_logger 39 | 40 | LogBuddy.init 41 | LogBuddy.logger.should == rails_default_logger 42 | ensure 43 | Object.send :remove_const, "Rails" 44 | Object.send :remove_const, "RAILS_DEFAULT_LOGGER" 45 | end 46 | end 47 | end 48 | end 49 | 50 | describe "outputting the code being logged and its result" do 51 | before { LogBuddy.init :log_to_stdout => false } 52 | it "should log to default logger" do 53 | LogBuddy.expects(:logger).returns(logger = mock) 54 | logger.expects(:debug).with(anything) 55 | d {'hi man'} 56 | end 57 | 58 | it "should log a plain method call as is, nothing fancy" do 59 | LogBuddy.expects(:debug).with("hey yo") 60 | d 'hey yo' 61 | end 62 | 63 | it "logs both argument and resulting value if using block from" do 64 | LogBuddy.expects(:debug).with("hi mom") 65 | LogBuddy.expects(:debug).with(%[foo = "foo"\n]) 66 | foo = "foo" 67 | d("hi mom") { foo } 68 | end 69 | 70 | it "does nothing without a block" do 71 | lambda { d }.should_not raise_error 72 | end 73 | 74 | it "should output only local vars in the block" do 75 | LogBuddy.expects(:debug).with(%[a = "foo"\n]) 76 | b = "bad" 77 | a = "foo" 78 | d { a } 79 | end 80 | 81 | it "should output instance vars" do 82 | LogBuddy.expects(:debug).with(%[@a = "foo"\n]) 83 | @a = "foo" 84 | d { @a } 85 | end 86 | 87 | it "should output constants" do 88 | FOO_CONST = "yo!" 89 | LogBuddy.expects(:debug).with(%[FOO_CONST = "yo!"\n]) 90 | d { FOO_CONST } 91 | end 92 | 93 | it "should output class vars" do 94 | LogBuddy.expects(:debug).with(%[@@class_var = "hi"\n]) 95 | @@class_var = "hi" 96 | d { @@class_var } 97 | end 98 | 99 | it "should output method calls" do 100 | LogBuddy.expects(:debug).with(%[SomeModule.say_something("dude!!!!") = "hello dude!!!!"\n]) 101 | d { SomeModule.say_something("dude!!!!") } 102 | end 103 | 104 | it "should output multiple things with each having their own log calls" do 105 | local1 = '1' 106 | local2 = '2' 107 | @ivar1 = '1' 108 | LogBuddy.expects(:debug).with(%[local1 = "1"\n]) 109 | LogBuddy.expects(:debug).with(%[local2 = "2"\n]) 110 | LogBuddy.expects(:debug).with(%[@ivar1 = "1"\n]) 111 | d { local1; local2; @ivar1 } 112 | end 113 | 114 | it "logs things okay with inline rdoc" do 115 | LogBuddy.stubs(:debug) 116 | hsh = {:foo=>"bar", "key"=>"value"} 117 | d { hsh } # hsh = {:foo=>"bar", "key"=>"value"} 118 | end 119 | 120 | it "logs inspected version of hashes and arrays" do 121 | hsh = { :peanut_butter => "jelly", "awesome_numbers" => [3,7,22]} 122 | different_hash_output_orders = [ 123 | %[hsh = {"awesome_numbers"=>[3, 7, 22], :peanut_butter=>"jelly"}\n], 124 | %[hsh = {:peanut_butter=>"jelly", "awesome_numbers"=>[3, 7, 22]}\n] 125 | ] 126 | LogBuddy.logger.expects(:debug).with(any_of(*different_hash_output_orders)) 127 | d { hsh } 128 | end 129 | 130 | describe "error cases" do 131 | 132 | it "should gracefully handle runtimer errors" do 133 | LogBuddy.expects(:debug).with('LogBuddy caught an exception: RuntimeError') 134 | d { SomeModule.raise_runtime_error } 135 | end 136 | 137 | it "gracefully handles case where the line of code is empty" do 138 | LogBuddy.expects(:read_line).returns("") 139 | lambda { 140 | d { SomeModule.raise_runtime_error } 141 | }.should_not raise_error 142 | end 143 | end 144 | 145 | 146 | end 147 | 148 | describe "obj_to_string" do 149 | include LogBuddy::Utils 150 | 151 | class Foo 152 | def inspect 153 | "inspeck yo-self" 154 | end 155 | 156 | def ai 157 | "awesome_print y0" 158 | end 159 | end 160 | 161 | it "logs string as-is" do 162 | obj_to_string("foo").should == "foo" 163 | end 164 | 165 | it "logs exception with exception msg, type, and backtrace" do 166 | begin 167 | raise "bad mojo" 168 | rescue Exception => exception 169 | string = obj_to_string(exception) 170 | string.should match /^bad mojo (RuntimeError)*/ 171 | string.should include(__FILE__) 172 | end 173 | end 174 | 175 | it "logs all other objects with #inspect" do 176 | obj_to_string(Foo.new).should == "inspeck yo-self" 177 | end 178 | 179 | it "logs object using awesome_print" do 180 | LogBuddy.init :use_awesome_print => true 181 | obj_to_string(Foo.new).should == "awesome_print y0" 182 | end 183 | end 184 | 185 | describe "stdout" do 186 | before { Logger.any_instance.stubs(:debug) } 187 | it "logs to stdout as well as the default logger" do 188 | LogBuddy.init :log_to_stdout => true 189 | LogBuddy.expects(:stdout_puts).with(%["foo" = "foo"\n]) 190 | d { "foo" } 191 | end 192 | 193 | it "doesnt log to stdout if stdout configured off" do 194 | LogBuddy.init :log_to_stdout => false 195 | LogBuddy.expects(:stdout_puts).never 196 | d { "foo" } 197 | end 198 | end 199 | end --------------------------------------------------------------------------------