cute_print 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: []