cute_print 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/README.md +42 -1
  4. data/VERSION +1 -1
  5. data/cute_print.gemspec +25 -4
  6. data/features/call_chain.feature +6 -5
  7. data/features/configuring/configure_position_format.feature +1 -2
  8. data/features/inspect/core.feature +18 -0
  9. data/features/inspect/inspect_with_location.feature +1 -1
  10. data/features/support/env.rb +3 -3
  11. data/features/support/helpers/example.rb +11 -13
  12. data/features/support/helpers/example_runner.rb +24 -0
  13. data/features/support/helpers/fork_example_runner.rb +37 -0
  14. data/features/support/helpers/lib_path.rb +7 -0
  15. data/features/support/helpers/shell_example_runner.rb +26 -0
  16. data/features/support/step_definitions.rb +0 -6
  17. data/lib/cute_print/core.rb +3 -0
  18. data/lib/cute_print/core_ext.rb +2 -0
  19. data/lib/cute_print/cute_print.rb +83 -0
  20. data/lib/cute_print/format/inspect.rb +12 -0
  21. data/lib/cute_print/format/pretty_print.rb +17 -0
  22. data/lib/cute_print/format.rb +2 -0
  23. data/lib/cute_print/formatter.rb +15 -81
  24. data/lib/cute_print/inline_labeler.rb +36 -0
  25. data/lib/cute_print/labeler.rb +71 -0
  26. data/lib/cute_print/location.rb +4 -10
  27. data/lib/cute_print/location_label/filename.rb +19 -0
  28. data/lib/cute_print/location_label/path.rb +19 -0
  29. data/lib/cute_print/location_label.rb +23 -0
  30. data/lib/cute_print/mixin.rb +13 -12
  31. data/lib/cute_print/outline_labeler.rb +38 -0
  32. data/lib/cute_print/printer.rb +4 -36
  33. data/lib/cute_print/source_label.rb +26 -0
  34. data/lib/cute_print.rb +1 -25
  35. data/spec/format/inspect_spec.rb +20 -0
  36. data/spec/format/pretty_print_spec.rb +36 -0
  37. data/spec/inline_labeler_spec.rb +39 -0
  38. data/spec/labeler_spec.rb +97 -0
  39. data/spec/outline_labeler_spec.rb +37 -0
  40. metadata +24 -3
  41. data/lib/cute_print/default_printer.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74ff62c5850c2503e438573080264cf4a70b019a
4
- data.tar.gz: 77872c08f0efe90db4a30ec5d2bed7fae48186a4
3
+ metadata.gz: 38450810673262d8825d6c9e249b8372df8f46a1
4
+ data.tar.gz: 1a6af72afb22b28d3a940eb7e117457c8dc1b90c
5
5
  SHA512:
6
- metadata.gz: b98616421885ff3035e7090ff3ab7ea0dc823cfe1dbc51c06e866058ac059da12f2a4e518cb58b2bfca92f9ac2dfc141a3ffbd763a67682d6e3168a9e9ca880d
7
- data.tar.gz: e43cef47529e511e49636874265a61249c3bf23cfb0a24e96f5aa87592d8593ef33da858b342d33b13806f4ed294f997fcabd125c65911b7d2732ecfc218d8a1
6
+ metadata.gz: ac83eb665b16c82b9736eb1d8ff7719ff1590b7a2ed6631d927d59c7a35a4d519e3b5a311065354188e57f8830737baeabadd5acc752a417d25a62435ea0ccc0
7
+ data.tar.gz: adaa3bc601bcbbd863949801d96f13af40db7017bf546f172550881c9eec14489beda90135ba2ea6e215e4afe4bb94ffe16fb390d773c3a4f0a4ec308a5adf8c
data/CHANGELOG.md CHANGED
@@ -1,9 +1,18 @@
1
+ ### Development
2
+
3
+ ### 0.4.0 2014-10-25
4
+
5
+ API changes
6
+
7
+ * Can be used without patching any core Ruby classes (see README)
8
+ * Use fewer output lines when possible while better respecting term width
9
+
1
10
  ### 0.3.0 / 2014-09-27
2
11
 
3
12
  Breaking changes:
4
13
 
5
14
  * Configure.out must respond to #print rather than #puts
6
- # Kernel#q, #qq and #qql return nil
15
+ * Kernel#q, #qq and #qql return nil
7
16
 
8
17
  Enhancements:
9
18
 
data/README.md CHANGED
@@ -8,6 +8,17 @@ Write debug output to stderr. Optionally print the source filename
8
8
  and line number, or the source of the debug statement. Easily inspect
9
9
  the middle of a call chain.
10
10
 
11
+ ## Why?
12
+
13
+ * You want to print debug output very quickly, and remove it just as
14
+ quickly.
15
+ * You want to easily label the debug output with the source
16
+ location.
17
+ * You want to easily label the debug output with the debug
18
+ code itself.
19
+ * You want to easily debug the middle of a call chain.
20
+ * You are debugging a program that is run with stdout redirected.
21
+
11
22
  ## Links
12
23
 
13
24
  * This is a [rubygem](http://rubygems.org/gems/cute_print)
@@ -15,7 +26,7 @@ the middle of a call chain.
15
26
  * Cucumber-driven documentation is on
16
27
  [relishapp](https://www.relishapp.com/wconrad/cute-print/v/0-2-0/docs)
17
28
  * API docs are at
18
- [rubydoc.info](http://rubydoc.info/gems/cute_print/0.2.0/frames)
29
+ [rubydoc.info](http://rubydoc.info/gems/cute_print)
19
30
 
20
31
  ## Installation
21
32
 
@@ -71,6 +82,15 @@ it even get to that method?"
71
82
  # 20,
72
83
  # 30]
73
84
 
85
+ When called with a bock, qq prints the debug source as well:
86
+
87
+ a = (1..30).to_a
88
+ qq {a} # a is [1,
89
+ # 2,
90
+ # ...
91
+ # 20,
92
+ # 30]
93
+
74
94
  **qql** also prints the source location:
75
95
 
76
96
  a = (1..30).to_a
@@ -80,6 +100,15 @@ it even get to that method?"
80
100
  # 20,
81
101
  # 30]
82
102
 
103
+ When called with a block, qql prints the debug source as well:
104
+
105
+ a = (1..30).to_a
106
+ qq {a} # foo.rb:12: a is [1,
107
+ # 2,
108
+ # ...
109
+ # 20,
110
+ # 30]
111
+
83
112
  **tapq** inspects the middle of a call chain:
84
113
 
85
114
  ["1", "2"].map(&:to_i).tapq.inject(&:+)
@@ -131,6 +160,18 @@ To reset the configuration to its defaults:
131
160
  c.reset
132
161
  end
133
162
 
163
+ ## Without modifying Ruby classes
164
+
165
+ By default, this gem defines many methods on Object, making them
166
+ globally available. To use this gem without any global methods,
167
+ require "cute_print/core" and then call one of the CutePrint class
168
+ methods:
169
+
170
+ require "cute_print/core"
171
+ CutePrint.q {1 + 2} # 1 + 2 is 3
172
+
173
+ The "tap" methods are not available when using CutePrint this way.
174
+
134
175
  ## Rubies supported
135
176
 
136
177
  This gem is known to work with these Rubies:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
data/cute_print.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: cute_print 0.3.0 ruby lib
5
+ # stub: cute_print 0.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cute_print"
9
- s.version = "0.3.0"
9
+ s.version = "0.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Wayne Conrad"]
14
- s.date = "2014-09-27"
14
+ s.date = "2014-10-26"
15
15
  s.description = "Write debug output to stderr. Optionally print the source filename and line number, or the source of the debug statement. Easily inspect the middle of a call chain."
16
16
  s.email = "wconrad@yagni.com"
17
17
  s.extra_rdoc_files = [
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
37
37
  "features/configuring/configure_position_format.feature",
38
38
  "features/configuring/readme.md",
39
39
  "features/configuring/reset_configuration.feature",
40
+ "features/inspect/core.feature",
40
41
  "features/inspect/inspect.feature",
41
42
  "features/inspect/inspect_with_location.feature",
42
43
  "features/inspect/inspect_with_source.feature",
@@ -47,18 +48,32 @@ Gem::Specification.new do |s|
47
48
  "features/readme.md",
48
49
  "features/support/env.rb",
49
50
  "features/support/helpers/example.rb",
51
+ "features/support/helpers/example_runner.rb",
52
+ "features/support/helpers/fork_example_runner.rb",
53
+ "features/support/helpers/lib_path.rb",
54
+ "features/support/helpers/shell_example_runner.rb",
50
55
  "features/support/helpers/temp_dir.rb",
51
56
  "features/support/step_definitions.rb",
52
57
  "lib/cute_print.rb",
53
58
  "lib/cute_print/configure.rb",
59
+ "lib/cute_print/core.rb",
54
60
  "lib/cute_print/core_ext.rb",
55
61
  "lib/cute_print/core_ext/irb.rb",
56
62
  "lib/cute_print/core_ext/object.rb",
57
- "lib/cute_print/default_printer.rb",
63
+ "lib/cute_print/cute_print.rb",
58
64
  "lib/cute_print/finds_foreign_caller.rb",
65
+ "lib/cute_print/format.rb",
66
+ "lib/cute_print/format/inspect.rb",
67
+ "lib/cute_print/format/pretty_print.rb",
59
68
  "lib/cute_print/formatter.rb",
69
+ "lib/cute_print/inline_labeler.rb",
70
+ "lib/cute_print/labeler.rb",
60
71
  "lib/cute_print/location.rb",
72
+ "lib/cute_print/location_label.rb",
73
+ "lib/cute_print/location_label/filename.rb",
74
+ "lib/cute_print/location_label/path.rb",
61
75
  "lib/cute_print/mixin.rb",
76
+ "lib/cute_print/outline_labeler.rb",
62
77
  "lib/cute_print/printer.rb",
63
78
  "lib/cute_print/ruby_generator.rb",
64
79
  "lib/cute_print/ruby_parser.rb",
@@ -66,9 +81,15 @@ Gem::Specification.new do |s|
66
81
  "lib/cute_print/ruby_parser/method_call.rb",
67
82
  "lib/cute_print/ruby_parser/parsed_code.rb",
68
83
  "lib/cute_print/ruby_parser/wraps_sexp.rb",
84
+ "lib/cute_print/source_label.rb",
69
85
  "lib/cute_print/stderr_out.rb",
70
86
  "spec/cute_print_spec.rb",
87
+ "spec/format/inspect_spec.rb",
88
+ "spec/format/pretty_print_spec.rb",
89
+ "spec/inline_labeler_spec.rb",
71
90
  "spec/irb_spec.rb",
91
+ "spec/labeler_spec.rb",
92
+ "spec/outline_labeler_spec.rb",
72
93
  "spec/printer_spec.rb",
73
94
  "spec/spec_helper.rb",
74
95
  "spec/support/captures_stderr.rb",
@@ -86,10 +86,11 @@ Feature: Inspect a call chain
86
86
  """
87
87
  And stderr should be
88
88
  """
89
- example.rb:9: ["Once upon a time there were four little Rabbits, and their names were",
90
- "Flopsy,",
91
- "Mopsy,",
92
- "Cotton-tail, and",
93
- "Peter."]
89
+ example.rb:9:
90
+ ["Once upon a time there were four little Rabbits, and their names were",
91
+ "Flopsy,",
92
+ "Mopsy,",
93
+ "Cotton-tail, and",
94
+ "Peter."]
94
95
 
95
96
  """
@@ -17,8 +17,7 @@ Feature: Configure location format
17
17
  """
18
18
  Then stderr should be
19
19
  """
20
- /tmp/.../example.rb:7:
21
- 123
20
+ /tmp/.../example.rb:7: 123
22
21
 
23
22
  """
24
23
 
@@ -0,0 +1,18 @@
1
+ Feature: Core functionality
2
+
3
+ cute_print, by default, adds a fair number of methods to Object,
4
+ making them available globally. You can use cute_print without any
5
+ changes to Object, by requiring "cute_print/core" instead of
6
+ "cute_print".
7
+
8
+ Scenario: Inspect an object
9
+ Given a file with:
10
+ """
11
+ require "cute_print/core"
12
+ CutePrint.q "abc"
13
+ """
14
+ Then stderr should be
15
+ """
16
+ "abc"
17
+
18
+ """
@@ -29,7 +29,7 @@ Feature: Inspect with source location
29
29
 
30
30
  """
31
31
 
32
- Scenario: Inspect with location
32
+ Scenario: Inspect with source
33
33
  Given a file named "example.rb" with:
34
34
  """
35
35
  require "cute_print"
@@ -1,9 +1,9 @@
1
1
  require "rspec/expectations"
2
2
 
3
3
  # Instead of letting cucumber load all of the .rb, we configure
4
- # cucumber to require them (see .config/cucumber.yml).
4
+ # cucumber to require them (in .config/cucumber.yml)
5
+
5
6
  glob = File.join(File.dirname(__FILE__), '**/*.rb')
6
- ruby_paths = Dir[glob].sort
7
- ruby_paths.each do |path|
7
+ Dir[glob].sort.each do |path|
8
8
  require path
9
9
  end
@@ -1,13 +1,8 @@
1
- require_relative "../../../test_support/captures_stderr.rb"
2
- require_relative "../../../test_support/captures_stdout.rb"
3
-
1
+ require_relative "example_runner"
4
2
  require_relative "temp_dir"
5
3
 
6
4
  class Example
7
5
 
8
- include CapturesStderr
9
- include CapturesStdout
10
-
11
6
  def initialize(contents, opts = {})
12
7
  @contents = contents
13
8
  @filename = opts.fetch(:filename, "example.rb")
@@ -16,21 +11,24 @@ class Example
16
11
  end
17
12
 
18
13
  def run
19
- @stdout = capture_stdout do
20
- @stderr = capture_stderr do
21
- load path
14
+ ExampleRunner.run(path) do |stdout, stderr, exit_status|
15
+ @stdout = stdout
16
+ @stderr = stderr
17
+ @exit_status = exit_status
18
+ if @exit_status != 0
19
+ fail "Failed: #{@stdout}\n#{@stderr}"
22
20
  end
23
21
  end
24
22
  end
25
23
 
26
- def stderr
27
- filter_output(@stderr)
28
- end
29
-
30
24
  def stdout
31
25
  filter_output(@stdout)
32
26
  end
33
27
 
28
+ def stderr
29
+ filter_output(@stderr)
30
+ end
31
+
34
32
  private
35
33
 
36
34
  def create_file
@@ -0,0 +1,24 @@
1
+ require "open3"
2
+
3
+ require_relative "fork_example_runner"
4
+ require_relative "shell_example_runner"
5
+
6
+ class ExampleRunner
7
+
8
+ def self.run(*args, &block)
9
+ instance.run(*args, &block)
10
+ end
11
+
12
+ def self.instance
13
+ @instance ||= make
14
+ end
15
+
16
+ def self.make
17
+ if ForkExampleRunner.supported?
18
+ ForkExampleRunner.new
19
+ else
20
+ ShellExampleRunner.new
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "../../../test_support/captures_stderr"
2
+ require_relative "../../../test_support/captures_stdout"
3
+ require_relative "lib_path"
4
+
5
+ require "open3"
6
+
7
+ # This example runner is relatively fast, but isn't available on all
8
+ # platforms.
9
+ class ForkExampleRunner
10
+
11
+ include CapturesStderr
12
+ include CapturesStdout
13
+ include LibPath
14
+
15
+ def self.supported?
16
+ Process.respond_to?(:fork)
17
+ end
18
+
19
+ def run(path)
20
+ stdout_rd, stdout_wr = IO.pipe
21
+ stderr_rd, stderr_wr = IO.pipe
22
+ pid = fork do
23
+ $stdout.reopen stdout_wr
24
+ $stderr.reopen stderr_wr
25
+ load path
26
+ exit! 0
27
+ end
28
+ Process.wait(pid)
29
+ exit_status = $?
30
+ stdout_wr.close
31
+ stderr_wr.close
32
+ stdout = stdout_rd.read
33
+ stderr = stderr_rd.read
34
+ yield stdout, stderr, exit_status
35
+ end
36
+
37
+ end
@@ -0,0 +1,7 @@
1
+ module LibPath
2
+
3
+ def lib_path
4
+ File.join(File.dirname(__FILE__), '../../../lib')
5
+ end
6
+
7
+ end
@@ -0,0 +1,26 @@
1
+ require "open3"
2
+
3
+ require_relative "lib_path"
4
+
5
+ # This example runner is relatively slow, but should work on platforms
6
+ # which do not support fork, such as Windows.
7
+ class ShellExampleRunner
8
+
9
+ include LibPath
10
+
11
+ def run(path)
12
+ command = [
13
+ "ruby",
14
+ "-I", lib_path,
15
+ path,
16
+ ]
17
+ Open3.popen3(*command) do |stdin, stdout, stderr, wait_thr|
18
+ stdin.close
19
+ stdout = stdout.read
20
+ stderr = stderr.read
21
+ exit_status = wait_thr.value
22
+ yield stdout, stderr, exit_status
23
+ end
24
+ end
25
+
26
+ end
@@ -1,9 +1,3 @@
1
- require_relative "../../lib/cute_print"
2
-
3
- Before do
4
- CutePrint.configure { |c| c.reset }
5
- end
6
-
7
1
  Given(/^a file with:$/) do |contents|
8
2
  @example = Example.new(contents)
9
3
  @example.run
@@ -0,0 +1,3 @@
1
+ # Require this file to get everything except the monkey-patches.
2
+
3
+ require_relative "cute_print"
@@ -1,2 +1,4 @@
1
+ # Load all monkey-patches
2
+
1
3
  require_relative "core_ext/irb"
2
4
  require_relative "core_ext/object"
@@ -0,0 +1,83 @@
1
+ require_relative "configure"
2
+ require_relative "printer"
3
+
4
+ # Like Kernel#p, only fancier. For example, this code:
5
+ #
6
+ # require "cute_print"
7
+ # q { 1 + 2 }
8
+ #
9
+ # prints this to $stderr:
10
+ #
11
+ # (1 + 2) is 3
12
+ module CutePrint
13
+
14
+ # Configure the library. For example:
15
+ #
16
+ # CutePrint.configure do |c|
17
+ # c.out = $stdout
18
+ # end
19
+ #
20
+ # @yieldparam config [Configure]
21
+ def self.configure(&block)
22
+ Configure.new(printer, &block)
23
+ end
24
+
25
+ # @return [Printer] the singleton printer
26
+ # @api private
27
+ def self.printer
28
+ @printer ||= Printer.new
29
+ end
30
+
31
+ # Inspect and write one or more objects.
32
+ #
33
+ # If called without a block, prints the inspected arguments, one
34
+ # on a line.
35
+ #
36
+ # If called with a block, prints the source code of the block and
37
+ # the inspected result of the block.
38
+ #
39
+ # @return nil
40
+ def self.q(*args, &block)
41
+ printer.q(*args, &block)
42
+ end
43
+
44
+ # Inspect and write one or more objects, with source location.
45
+ #
46
+ # If called without a block, prints the inspected arguments, one
47
+ # on a line.
48
+ #
49
+ # If called with a block, prints the source code of the block and
50
+ # the inspected result of the block.
51
+ #
52
+ # @return nil
53
+ def self.ql(*args, &block)
54
+ printer.ql(*args, &block)
55
+ end
56
+
57
+ # Pretty-print and write one or more objects.
58
+ #
59
+ # If called without a block, pretty-prints the pretty-printed
60
+ # arguments, one on a line.
61
+ #
62
+ # If called with a block, prints the source code of the block and
63
+ # pretty-prints the result of the block.
64
+ #
65
+ # @return nil
66
+ def self.qq(*args, &block)
67
+ printer.qq(*args, &block)
68
+ end
69
+
70
+ # Pretty-print and write one or more objects, with source location.
71
+ #
72
+ # If called without a block, pretty-prints the arguments, one on a
73
+ # line.
74
+ #
75
+ # If called with a block, prints the source code of the block and
76
+ # pretty-prints the result of the block.
77
+ #
78
+ # @return nil
79
+ def self.qql(*args, &block)
80
+ printer.qql(*args, &block)
81
+ end
82
+
83
+ end
@@ -0,0 +1,12 @@
1
+ module CutePrint
2
+ module Format
3
+ # @api private
4
+ class Inspect
5
+
6
+ def format(width, value)
7
+ [value.inspect + "\n"]
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require 'pp'
2
+ require 'stringio'
3
+
4
+ module CutePrint
5
+ module Format
6
+ # @api private
7
+ class PrettyPrint
8
+
9
+ def format(width, value)
10
+ out = StringIO.new
11
+ PP.pp(value, out, width)
12
+ out.string.lines
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ require_relative "format/inspect"
2
+ require_relative "format/pretty_print"