cute_print 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"