cute_print 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzAxMjU2ZDA2ZjFlYjJmOThhOWZkYTlhZjMxNzVlYjI4ZGY2ZTNjMQ==
5
- data.tar.gz: !binary |-
6
- ODA2ZGNjNTQ0M2EzMTBlYmEyMTg2M2ZhZTg4NzEzOWM4MmE4Zjk5Nw==
2
+ SHA1:
3
+ metadata.gz: 74ff62c5850c2503e438573080264cf4a70b019a
4
+ data.tar.gz: 77872c08f0efe90db4a30ec5d2bed7fae48186a4
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- N2U5OGFkZTMwZDFiNTNhNjRlNjA3NTliNzM1OWFmMjg0ZGViZWRmZDE1MWE0
10
- YzJiNjhmZmM2NDMzZWVkNWY1NzU2ZmVhODRiNzA2NWVlY2NmMzM5MjIyOTY0
11
- NzBmMWFlYzRjZTRlOTgyYjRkMmMxMmM0ZmE3NTMzZmE0MjM3Mzc=
12
- data.tar.gz: !binary |-
13
- ZmU3NjFhOGNhODVkN2EwMWYwZDFhY2FlZDBiNzQwYjA3MDQxN2FiZjUwMGIy
14
- ZWIzM2MzN2YxMzdlMGM4NTY5NWRhNWZjYjNlNjQwZjNlMjdjYzFhODAwNzA2
15
- N2JlNGVjYTNhMDMyMDk2YWZjOWI1YzcwNWJmYjgzNDk5ZThkNGY=
6
+ metadata.gz: b98616421885ff3035e7090ff3ab7ea0dc823cfe1dbc51c06e866058ac059da12f2a4e518cb58b2bfca92f9ac2dfc141a3ffbd763a67682d6e3168a9e9ca880d
7
+ data.tar.gz: e43cef47529e511e49636874265a61249c3bf23cfb0a24e96f5aa87592d8593ef33da858b342d33b13806f4ed294f997fcabd125c65911b7d2732ecfc218d8a1
data/CHANGELOG.md CHANGED
@@ -1,4 +1,21 @@
1
- ### Development
1
+ ### 0.3.0 / 2014-09-27
2
+
3
+ Breaking changes:
4
+
5
+ * Configure.out must respond to #print rather than #puts
6
+ # Kernel#q, #qq and #qql return nil
7
+
8
+ Enhancements:
9
+
10
+ * Added Kernel#tapqq (call chain pretty-print)
11
+ * Added Kernel#tapqql (call chain pretty-print, with source location)
12
+
13
+ Bug fixes:
14
+
15
+ * Works in irb (issue #1)
16
+ * Is now thread safe (issue #4)
17
+
18
+ ### 0.2.0 / 2014-09-05
2
19
 
3
20
  Breaking changes:
4
21
 
data/Gemfile.lock CHANGED
@@ -3,7 +3,7 @@ GEM
3
3
  specs:
4
4
  addressable (2.3.6)
5
5
  builder (3.2.2)
6
- cucumber (1.3.16)
6
+ cucumber (1.3.17)
7
7
  builder (>= 2.1.2)
8
8
  diff-lcs (>= 1.1.3)
9
9
  gherkin (~> 2.12)
@@ -55,28 +55,28 @@ GEM
55
55
  rack (~> 1.2)
56
56
  rack (1.5.2)
57
57
  rake (10.3.2)
58
- rdoc (4.1.1)
58
+ rdoc (4.1.2)
59
59
  json (~> 1.4)
60
60
  redcarpet (3.1.2)
61
- rspec (3.0.0)
62
- rspec-core (~> 3.0.0)
63
- rspec-expectations (~> 3.0.0)
64
- rspec-mocks (~> 3.0.0)
65
- rspec-core (3.0.4)
66
- rspec-support (~> 3.0.0)
67
- rspec-expectations (3.0.4)
61
+ rspec (3.1.0)
62
+ rspec-core (~> 3.1.0)
63
+ rspec-expectations (~> 3.1.0)
64
+ rspec-mocks (~> 3.1.0)
65
+ rspec-core (3.1.4)
66
+ rspec-support (~> 3.1.0)
67
+ rspec-expectations (3.1.2)
68
68
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.0.0)
69
+ rspec-support (~> 3.1.0)
70
70
  rspec-given (3.5.4)
71
71
  given_core (= 3.5.4)
72
72
  rspec (>= 2.12)
73
- rspec-mocks (3.0.4)
74
- rspec-support (~> 3.0.0)
75
- rspec-support (3.0.4)
76
- ruby2ruby (2.1.2)
73
+ rspec-mocks (3.1.2)
74
+ rspec-support (~> 3.1.0)
75
+ rspec-support (3.1.1)
76
+ ruby2ruby (2.1.3)
77
77
  ruby_parser (~> 3.1)
78
78
  sexp_processor (~> 4.0)
79
- ruby_parser (3.6.2)
79
+ ruby_parser (3.6.3)
80
80
  sexp_processor (~> 4.1)
81
81
  sexp_processor (4.4.4)
82
82
  sorcerer (1.0.2)
data/README.md CHANGED
@@ -5,20 +5,17 @@
5
5
  [![Code Climate](https://codeclimate.com/github/wconrad/cute_print.png)](https://codeclimate.com/github/wconrad/cute_print)
6
6
 
7
7
  Write debug output to stderr. Optionally print the source filename
8
- and line number, or the source of the debug statement. Easily debug
8
+ and line number, or the source of the debug statement. Easily inspect
9
9
  the middle of a call chain.
10
10
 
11
- ## Features
11
+ ## Links
12
12
 
13
- * Inspects its output, like Kernel#p.
14
- * Writes to $stderr by default (good when $stdout is redirected).
15
- * Can print the filename and line number.
16
- * Can print the source of the value.
17
- * Can print a value in the middle of a call chain.
18
- * Configurable output device.
19
-
20
- This is for those who prefer to debug by writing things to the
21
- console.
13
+ * This is a [rubygem](http://rubygems.org/gems/cute_print)
14
+ * The source is on [github](https://github.com/wconrad/cute_print)
15
+ * Cucumber-driven documentation is on
16
+ [relishapp](https://www.relishapp.com/wconrad/cute-print/v/0-2-0/docs)
17
+ * API docs are at
18
+ [rubydoc.info](http://rubydoc.info/gems/cute_print/0.2.0/frames)
22
19
 
23
20
  ## Installation
24
21
 
@@ -30,7 +27,7 @@ And then execute:
30
27
 
31
28
  $ bundle
32
29
 
33
- Or install it yourself as:
30
+ Or install it yourself:
34
31
 
35
32
  $ gem install cute_print
36
33
 
@@ -40,46 +37,107 @@ Start with:
40
37
 
41
38
  require "cute_print"
42
39
 
43
- You can use q just like you use Kernel#p. It will work the same,
44
- except that its output goes to $stderr instead of $stdout:
40
+ **q** work like
41
+ [Kernel#p](http://www.ruby-doc.org/core-2.1.3/Kernel.html#method-i-p),
42
+ except that it prints to $stderr instead of $stdout.
45
43
 
46
44
  q "abc" # "abc"
47
45
  q [1, 2, 3 + 4] # [1, 2, 7]
48
46
 
49
- You can have the debug source printed along with the value:
47
+ By passing a block, you can have the debug source printed along with
48
+ the value:
50
49
 
51
50
  i = 1
52
51
  q {i + 2} # i + 2 is 3
53
52
 
54
- Kernel#ql will add the source location:
53
+ **ql** will also print the source location:
55
54
 
56
55
  ql "abc" # foo.rb:12: "abc"
57
56
  ql {1 + 2} # foo.rb:13: 1 + 2 is 3
58
57
 
59
- When called with no arguments, #ql just prints the source location:
58
+ When called with no arguments, ql just prints the source location:
60
59
 
61
60
  ql # foo.rb:14
62
61
 
63
- Call chains can be a pain to debug, but it's easy with Kernel#tapq and
64
- Kernel#tapql:
62
+ This is very handy for answering "which branch did it take?," or "did
63
+ it even get to that method?"
64
+
65
+ **qq** pretty-prints its arguments to $stderr:
66
+
67
+ a = (1..30).to_a
68
+ qq a # [1,
69
+ # 2,
70
+ # ...
71
+ # 20,
72
+ # 30]
73
+
74
+ **qql** also prints the source location:
75
+
76
+ a = (1..30).to_a
77
+ qq a # foo.rb:12: [1,
78
+ # 2,
79
+ # ...
80
+ # 20,
81
+ # 30]
82
+
83
+ **tapq** inspects the middle of a call chain:
65
84
 
66
85
  ["1", "2"].map(&:to_i).tapq.inject(&:+)
67
86
  # [1, 2]
68
87
 
88
+ **tapql** also prints the source location:
89
+
69
90
  ["1", "2"].map(&:to_i).tapql.inject(&:+)
70
- # prints: bar.rb:12: [1, 2]
91
+ # bar.rb:12: [1, 2]
92
+
93
+ **tapqq** pretty-prints the middle of a call chain:
94
+
95
+ a = (1..30).to_a
96
+ sum = a.tapqq.inject(:+) # [1,
97
+ # 2,
98
+ # ...
99
+ # 20,
100
+ # 30]
71
101
 
72
- ## Documentation
102
+ **tapqql** also prints the source location:
73
103
 
74
- There's more. Please see the [Full documentation][2] (relishapp).
104
+ a = (1..30).to_a
105
+ sum = a.tapqq.inject(:+) # foo.rb:12: [1,
106
+ # 2,
107
+ # ...
108
+ # 20,
109
+ # 30]
110
+
111
+ ## Configuration
112
+
113
+ To change the output device:
114
+
115
+ CutePrint.configure do |c|
116
+ c.out = File.open('/tmp/debug')
117
+ end
118
+
119
+ Any object that responds to #print will do.
120
+
121
+ To cause #ql, #qql and #tapql to print the full path rather than just
122
+ the filename:
123
+
124
+ CutePrint.configure do |c|
125
+ c.location_format = :path
126
+ end
127
+
128
+ To reset the configuration to its defaults:
129
+
130
+ CutePrint.configure do |c|
131
+ c.reset
132
+ end
75
133
 
76
134
  ## Rubies supported
77
135
 
78
136
  This gem is known to work with these Rubies:
79
137
 
80
- * ruby-1.9.3-p547
81
- * ruby-2.0.0-p481
82
- * ruby-2.1.2p95
138
+ * ruby-1.9.3
139
+ * ruby-2.0.0
140
+ * ruby-2.1.2
83
141
 
84
142
  ## Platforms supported
85
143
 
@@ -93,18 +151,6 @@ The [_wrong_][1] gem includes the excellent #d method, which is very
93
151
  much like this gem's #q method. This gem's ability to read the debug
94
152
  statement's source is derived from the _wrong_ gem.
95
153
 
96
- Differences between the _wrong_ gem and this gem:
97
-
98
- * This gem can print the source location
99
- * This gem writes to $stderr
100
- * This gem's output is configurable
101
- * This gem requires Ruby >= 1.9
102
- * This gem debugs call chains
103
- * The _wrong_ gem supports color output
104
- * The _wrong_ gem writes to stdout
105
- * The _wrong_ gem supports Ruby 1.8
106
- * The _wrong_ gem has assertions and more
107
-
108
154
  ## Versioning
109
155
 
110
156
  This gem uses [semantic versioning 2.0][3].
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/cute_print.gemspec CHANGED
@@ -2,17 +2,17 @@
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.2.0 ruby lib
5
+ # stub: cute_print 0.3.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cute_print"
9
- s.version = "0.2.0"
9
+ s.version = "0.3.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-05"
15
- s.description = "Write debug output to stderr. Optionally print the source filename and line number, or the source of the debug statement. Easily debug the middle of a call chain."
14
+ s.date = "2014-09-27"
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 = [
18
18
  "LICENSE",
@@ -52,6 +52,7 @@ Gem::Specification.new do |s|
52
52
  "lib/cute_print.rb",
53
53
  "lib/cute_print/configure.rb",
54
54
  "lib/cute_print/core_ext.rb",
55
+ "lib/cute_print/core_ext/irb.rb",
55
56
  "lib/cute_print/core_ext/object.rb",
56
57
  "lib/cute_print/default_printer.rb",
57
58
  "lib/cute_print/finds_foreign_caller.rb",
@@ -67,6 +68,7 @@ Gem::Specification.new do |s|
67
68
  "lib/cute_print/ruby_parser/wraps_sexp.rb",
68
69
  "lib/cute_print/stderr_out.rb",
69
70
  "spec/cute_print_spec.rb",
71
+ "spec/irb_spec.rb",
70
72
  "spec/printer_spec.rb",
71
73
  "spec/spec_helper.rb",
72
74
  "spec/support/captures_stderr.rb",
@@ -77,7 +79,8 @@ Gem::Specification.new do |s|
77
79
  "tasks/test.rake",
78
80
  "tasks/yard.rake",
79
81
  "test_support/captures_stderr.rb",
80
- "test_support/captures_stdout.rb"
82
+ "test_support/captures_stdout.rb",
83
+ "test_support/thread_unsafe_string_io.rb"
81
84
  ]
82
85
  s.homepage = "http://github.com/wconrad/cute_print"
83
86
  s.licenses = ["MIT"]
@@ -37,3 +37,59 @@ Feature: Inspect a call chain
37
37
  example.rb:2: [1, 2]
38
38
 
39
39
  """
40
+
41
+ Scenario: Pretty print
42
+ Given a file with:
43
+ """
44
+ require "cute_print"
45
+ a = [
46
+ "Once upon a time there were four little Rabbits, and their names were",
47
+ "Flopsy,",
48
+ "Mopsy,",
49
+ "Cotton-tail, and",
50
+ "Peter.",
51
+ ]
52
+ puts a.tapqq.map(&:size).inject(&:+)
53
+ """
54
+ Then stdout should be
55
+ """
56
+ 104
57
+
58
+ """
59
+ And stderr should be
60
+ """
61
+ ["Once upon a time there were four little Rabbits, and their names were",
62
+ "Flopsy,",
63
+ "Mopsy,",
64
+ "Cotton-tail, and",
65
+ "Peter."]
66
+
67
+ """
68
+
69
+ Scenario: Pretty print with source location
70
+ Given a file with:
71
+ """
72
+ require "cute_print"
73
+ a = [
74
+ "Once upon a time there were four little Rabbits, and their names were",
75
+ "Flopsy,",
76
+ "Mopsy,",
77
+ "Cotton-tail, and",
78
+ "Peter.",
79
+ ]
80
+ puts a.tapqql.map(&:size).inject(&:+)
81
+ """
82
+ Then stdout should be
83
+ """
84
+ 104
85
+
86
+ """
87
+ And stderr should be
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."]
94
+
95
+ """
@@ -0,0 +1,26 @@
1
+ # Taken, and then modified, from the _wrong_ gem:
2
+ # https://github.com/sconover/wrong/blob/30475fc5ac9d0f73135d229b1b44c045156a7e7a/lib/wrong/irb.rb
3
+ # Thanks for showing the way
4
+
5
+ if defined? IRB
6
+ module IRB
7
+ class Context
8
+
9
+ def all_lines
10
+ @all_lines.join
11
+ end
12
+
13
+ original_evaluate = instance_method(:evaluate)
14
+
15
+ # Save every line that is evaluated. This gives cute_print a
16
+ # way to get the source when it is run in irb.
17
+ define_method :evaluate do |line, line_no|
18
+ @all_lines ||= []
19
+ @all_lines += ["\n"] * (line_no - @all_lines.size - 1)
20
+ @all_lines[line_no - 1] = line
21
+ original_evaluate.bind(self).call line, line_no
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -1 +1,2 @@
1
+ require_relative "core_ext/irb"
1
2
  require_relative "core_ext/object"
@@ -117,7 +117,8 @@ module CutePrint
117
117
  end
118
118
 
119
119
  def write_line(line)
120
- @out.puts line
120
+ line += "\n" unless line =~ /\n\Z/
121
+ @out.print line
121
122
  end
122
123
 
123
124
  def label
@@ -44,5 +44,19 @@ module CutePrint
44
44
  self
45
45
  end
46
46
 
47
+ # Debug a call chain by pretty-printing self and then returning
48
+ # self.
49
+ def tapqq
50
+ qq self
51
+ self
52
+ end
53
+
54
+ # Debug a call chain by printing the source location,
55
+ # pretty-printing self, and then returning self.
56
+ def tapqql
57
+ qql self
58
+ self
59
+ end
60
+
47
61
  end
48
62
  end
@@ -7,7 +7,7 @@ module CutePrint
7
7
  include FindsForeignCaller
8
8
 
9
9
  # The object to write to. Defaults to $stderr.
10
- # @return [#puts]
10
+ # @return [#print]
11
11
  attr_accessor :out
12
12
 
13
13
  # The location format.
@@ -43,6 +43,8 @@ module CutePrint
43
43
  #
44
44
  # If called with a block, prints the source code of the block and
45
45
  # the inspected result of the block.
46
+ #
47
+ # @return nil
46
48
  def q(*values, &block)
47
49
  formatter = Formatter.new(
48
50
  method: __method__,
@@ -52,6 +54,7 @@ module CutePrint
52
54
  )
53
55
  formatter.inspect
54
56
  formatter.write
57
+ nil
55
58
  end
56
59
 
57
60
  # Inspect and write one or more objects, with source location.
@@ -61,6 +64,8 @@ module CutePrint
61
64
  #
62
65
  # If called with a block, prints the source code of the block and
63
66
  # the inspected result of the block.
67
+ #
68
+ # @return nil
64
69
  def ql(*values, &block)
65
70
  formatter = Formatter.new(
66
71
  method: __method__,
@@ -70,6 +75,7 @@ module CutePrint
70
75
  formatter.inspect
71
76
  formatter.with_location @location_format
72
77
  formatter.write
78
+ nil
73
79
  end
74
80
 
75
81
  # Pretty-print and write one or more objects.
@@ -79,6 +85,8 @@ module CutePrint
79
85
  #
80
86
  # If called with a block, prints the source code of the block and
81
87
  # pretty-prints the result of the block.
88
+ #
89
+ # @return nil
82
90
  def qq(*values, &block)
83
91
  formatter = Formatter.new(
84
92
  method: __method__,
@@ -87,15 +95,18 @@ module CutePrint
87
95
  values: values)
88
96
  formatter.pretty_print
89
97
  formatter.write
98
+ nil
90
99
  end
91
100
 
92
101
  # Pretty-print and write one or more objects, with source location.
93
102
  #
94
- # If called without a block, pretty-prints the pretty-printed
95
- # arguments, one on a line.
103
+ # If called without a block, pretty-prints the arguments, one on a
104
+ # line.
96
105
  #
97
106
  # If called with a block, prints the source code of the block and
98
107
  # pretty-prints the result of the block.
108
+ #
109
+ # @return nil
99
110
  def qql(*values, &block)
100
111
  formatter = Formatter.new(
101
112
  method: __method__,
@@ -105,6 +116,7 @@ module CutePrint
105
116
  formatter.pretty_print
106
117
  formatter.with_location @location_format
107
118
  formatter.write
119
+ nil
108
120
  end
109
121
 
110
122
  private
@@ -30,7 +30,11 @@ module CutePrint
30
30
  private
31
31
 
32
32
  def read_source
33
- File.read(@path)
33
+ if @path == '(irb)'
34
+ IRB.CurrentContext.all_lines
35
+ else
36
+ File.read(@path)
37
+ end
34
38
  end
35
39
 
36
40
  def parser
@@ -1,14 +1,18 @@
1
+ require 'forwardable'
2
+
1
3
  module CutePrint
2
4
 
3
- # Writing to an instance of this class, rather than directly to
4
- # $stderr, allows the tests to capture output by assigning to
5
- # $stderr.
5
+ # Writing to an instance of this class, rather than to an instance
6
+ # variable that was set to $stderr, allows the tests to capture
7
+ # output by assigning to $stderr.
6
8
  # @api private
7
9
  class StderrOut
8
10
 
9
- def puts(*args)
10
- $stderr.puts(*args)
11
- end
11
+ extend Forwardable
12
+
13
+ def_delegators :$stderr,
14
+ :puts,
15
+ :print
12
16
 
13
17
  end
14
18
  end
@@ -4,8 +4,10 @@ require "stringio"
4
4
 
5
5
  require "cute_print"
6
6
 
7
- # Test the library as the user uses it. The other specs test
8
- # internals.
7
+ # This spec tests the parts of the library, as the user sees it, that
8
+ # are not covered by a Cucumber feature.
9
+ #
10
+ # The other specs test internals.
9
11
 
10
12
  describe CutePrint do
11
13
 
@@ -16,79 +18,37 @@ describe CutePrint do
16
18
  describe "#q" do
17
19
  When(:stderr) do
18
20
  capture_stderr do
19
- q 123
21
+ @result = q 123
20
22
  end
21
23
  end
22
- Then { stderr == "123\n" }
24
+ Then { expect(@result).to be_nil }
23
25
  end
24
26
 
25
27
  describe "#ql" do
26
28
  When(:stderr) do
27
29
  capture_stderr do
28
- @location = [File.basename(__FILE__), __LINE__ + 1].join(":")
29
- ql 123
30
+ @result = ql 123
30
31
  end
31
32
  end
32
- Then { stderr == "#{@location}: 123\n" }
33
+ Then { expect(@result).to be_nil }
33
34
  end
34
35
 
35
- describe "#tapq" do
36
- When do
37
- @stderr = capture_stderr do
38
- @result = ["1", "2"].map(&:to_i).tapq.inject(:+)
39
- end
40
- end
41
- Then { @result == 3}
42
- Then { @stderr == "[1, 2]\n" }
43
- end
44
-
45
- describe "#tapql" do
36
+ describe "#qq" do
46
37
  When do
47
38
  @stderr = capture_stderr do
48
- @location = [File.basename(__FILE__), __LINE__ + 1].join(":")
49
- @result = ["1", "2"].map(&:to_i).tapql.inject(:+)
39
+ @result = qq 123
50
40
  end
51
41
  end
52
- Then { @result == 3}
53
- Then { @stderr == "#{@location}: [1, 2]\n" }
42
+ Then { expect(@result).to be_nil }
54
43
  end
55
44
 
56
- describe "#qq" do
57
- Given(:object) do
58
- [
59
- "Once upon a time there were four little Rabbits, and their names were",
60
- "Flopsy,",
61
- "Mopsy,",
62
- "Cotton-tail, and",
63
- "Peter.",
64
- ]
65
- end
66
- Given(:expected_output) do
67
- %Q'["Once upon a time there were four little Rabbits, and their names were",\n' +
68
- %Q' "Flopsy,",\n' +
69
- %Q' "Mopsy,",\n' +
70
- %Q' "Cotton-tail, and",\n' +
71
- %Q' "Peter."]\n'
72
- end
45
+ describe "#qql" do
73
46
  When do
74
47
  @stderr = capture_stderr do
75
- qq object
76
- end
77
- end
78
- Then { @stderr == expected_output }
79
- end
80
-
81
- describe 'configure output' do
82
- Given(:io) { StringIO.new }
83
- Given do
84
- CutePrint.configure do |c|
85
- c.out = io
48
+ @result = qql 123
86
49
  end
87
50
  end
88
- When do
89
- q 123
90
- end
91
- Then { io.string == "123\n" }
51
+ Then { expect(@result).to be_nil }
92
52
  end
93
53
 
94
54
  end
data/spec/irb_spec.rb ADDED
@@ -0,0 +1,22 @@
1
+ require_relative "spec_helper"
2
+
3
+ require "irb"
4
+ require "open3"
5
+ require "stringio"
6
+
7
+ require "cute_print"
8
+
9
+ describe CutePrint do
10
+
11
+ it "should be able to inspect source when called from irb" do
12
+ lib_path = File.join(File.dirname(__FILE__), "../lib/cute_print")
13
+ stdout, stderr = Open3.popen3("irb") do |stdin, stdout, stderr, wait_thr|
14
+ stdin.puts "require #{lib_path.inspect}"
15
+ stdin.puts "q {1 + 2}"
16
+ stdin.close
17
+ [stdout.read, stderr.read]
18
+ end
19
+ expect(stderr).to eq "(1 + 2) is 3\n"
20
+ end
21
+
22
+ end
data/spec/printer_spec.rb CHANGED
@@ -10,35 +10,35 @@ module CutePrint
10
10
 
11
11
  context "single value" do
12
12
  Given(:out) { StringIO.new }
13
- Given(:printer) { Printer.new(:out => out) }
13
+ Given(:printer) { Printer.new(out: out) }
14
14
  When { printer.q [1, 2] }
15
15
  Then { out.string == "[1, 2]\n" }
16
16
  end
17
17
 
18
18
  context "multiple values" do
19
19
  Given(:out) { StringIO.new }
20
- Given(:printer) { Printer.new(:out => out) }
20
+ Given(:printer) { Printer.new(out: out) }
21
21
  When { printer.q 1, 2 }
22
22
  Then { out.string == "1\n2\n" }
23
23
  end
24
24
 
25
25
  context "arguments and closure" do
26
26
  Given(:out) { StringIO.new }
27
- Given(:printer) { Printer.new(:out => out) }
27
+ Given(:printer) { Printer.new(out: out) }
28
28
  When(:result) { printer.q("foo") {1 + 2} }
29
29
  Then { result == Failure(ArgumentError) }
30
30
  end
31
31
 
32
32
  context "closure (one line)" do
33
33
  Given(:out) { StringIO.new }
34
- Given(:printer) { Printer.new(:out => out) }
34
+ Given(:printer) { Printer.new(out: out) }
35
35
  When { printer.q {1 + 2} }
36
36
  Then { out.string == "(1 + 2) is 3\n" }
37
37
  end
38
38
 
39
39
  context "closure (two lines)" do
40
40
  Given(:out) { StringIO.new }
41
- Given(:printer) { Printer.new(:out => out) }
41
+ Given(:printer) { Printer.new(out: out) }
42
42
  When do
43
43
  printer.q do
44
44
  (1 + 2)
@@ -47,11 +47,26 @@ module CutePrint
47
47
  Then { out.string == "(1 + 2) is 3\n" }
48
48
  end
49
49
 
50
+ context "multiple threads" do
51
+ Given(:out) { ThreadUnsafeStringIO.new }
52
+ Given(:printer) { Printer.new(out: out) }
53
+ When do
54
+ 10.times.map do
55
+ Thread.new do
56
+ 10.times do
57
+ printer.q "foo"
58
+ end
59
+ end
60
+ end.map(&:join)
61
+ end
62
+ Then { expect(out.string).to match /\A("foo"\n)+\Z/ }
63
+ end
64
+
50
65
  end
51
66
 
52
67
  describe "#ql" do
53
68
  Given(:out) { StringIO.new }
54
- Given(:printer) { Printer.new(:out => out) }
69
+ Given(:printer) { Printer.new(out: out) }
55
70
  When do
56
71
  @location = [File.basename(__FILE__), __LINE__ + 1].join(":")
57
72
  printer.ql [1, 2]
data/spec/spec_helper.rb CHANGED
@@ -5,9 +5,12 @@ require "pp"
5
5
  require "rspec"
6
6
  require "rspec-given"
7
7
 
8
- # Requires supporting files with custom matchers and macros, etc,
9
- # in ./support/ and its subdirectories.
10
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
11
-
12
- RSpec.configure do |config|
8
+ globs = [
9
+ "../test_support",
10
+ "support",
11
+ ].map do |dir|
12
+ File.join(File.dirname(__FILE__), dir, '**/*.rb')
13
+ end
14
+ Dir[*globs].each do |path|
15
+ require path
13
16
  end
@@ -1,5 +1,3 @@
1
- require_relative "../../test_support/captures_stderr"
2
-
3
1
  RSpec.configure do |c|
4
2
  c.include CapturesStderr
5
3
  end
@@ -0,0 +1,13 @@
1
+ # Ruby may implement #puts with two calls to #print: One for the
2
+ # value, and one for the new-line. Do that, in order to flush
3
+ # out thread-safety bugs.
4
+
5
+ class ThreadUnsafeStringIO < StringIO
6
+ def puts(*args)
7
+ args.each do |arg|
8
+ print arg
9
+ Thread.pass
10
+ print "\n"
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,46 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cute_print
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wayne Conrad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-05 00:00:00.000000000 Z
11
+ date: 2014-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_parser
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ruby2ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '2.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.1'
41
41
  description: Write debug output to stderr. Optionally print the source filename and
42
- line number, or the source of the debug statement. Easily debug the middle of a
43
- call chain.
42
+ line number, or the source of the debug statement. Easily inspect the middle of
43
+ a call chain.
44
44
  email: wconrad@yagni.com
45
45
  executables: []
46
46
  extensions: []
@@ -48,10 +48,10 @@ extra_rdoc_files:
48
48
  - LICENSE
49
49
  - README.md
50
50
  files:
51
- - .config/cucumber.yml
52
- - .rspec
53
- - .travis.yml
54
- - .yardopts
51
+ - ".config/cucumber.yml"
52
+ - ".rspec"
53
+ - ".travis.yml"
54
+ - ".yardopts"
55
55
  - CHANGELOG.md
56
56
  - Gemfile
57
57
  - Gemfile.lock
@@ -81,6 +81,7 @@ files:
81
81
  - lib/cute_print.rb
82
82
  - lib/cute_print/configure.rb
83
83
  - lib/cute_print/core_ext.rb
84
+ - lib/cute_print/core_ext/irb.rb
84
85
  - lib/cute_print/core_ext/object.rb
85
86
  - lib/cute_print/default_printer.rb
86
87
  - lib/cute_print/finds_foreign_caller.rb
@@ -96,6 +97,7 @@ files:
96
97
  - lib/cute_print/ruby_parser/wraps_sexp.rb
97
98
  - lib/cute_print/stderr_out.rb
98
99
  - spec/cute_print_spec.rb
100
+ - spec/irb_spec.rb
99
101
  - spec/printer_spec.rb
100
102
  - spec/spec_helper.rb
101
103
  - spec/support/captures_stderr.rb
@@ -107,6 +109,7 @@ files:
107
109
  - tasks/yard.rake
108
110
  - test_support/captures_stderr.rb
109
111
  - test_support/captures_stdout.rb
112
+ - test_support/thread_unsafe_string_io.rb
110
113
  homepage: http://github.com/wconrad/cute_print
111
114
  licenses:
112
115
  - MIT
@@ -117,12 +120,12 @@ require_paths:
117
120
  - lib
118
121
  required_ruby_version: !ruby/object:Gem::Requirement
119
122
  requirements:
120
- - - ! '>='
123
+ - - ">="
121
124
  - !ruby/object:Gem::Version
122
125
  version: '0'
123
126
  required_rubygems_version: !ruby/object:Gem::Requirement
124
127
  requirements:
125
- - - ! '>='
128
+ - - ">="
126
129
  - !ruby/object:Gem::Version
127
130
  version: '0'
128
131
  requirements: []