io-like 0.3.0 → 0.3.1

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 (62) hide show
  1. data/.yardopts +1 -0
  2. data/LICENSE +22 -57
  3. data/{LICENSE.rubyspec → LICENSE-rubyspec} +0 -0
  4. data/{NEWS → NEWS.md} +10 -5
  5. data/README.md +269 -0
  6. data/Rakefile +228 -0
  7. data/ruby.1.8.mspec +7 -0
  8. data/spec/binmode_spec.rb +29 -0
  9. data/spec/close_read_spec.rb +64 -0
  10. data/spec/close_spec.rb +36 -0
  11. data/spec/close_write_spec.rb +61 -0
  12. data/spec/closed_spec.rb +16 -0
  13. data/spec/each_byte_spec.rb +38 -0
  14. data/spec/each_line_spec.rb +11 -0
  15. data/spec/each_spec.rb +11 -0
  16. data/spec/eof_spec.rb +11 -0
  17. data/spec/fixtures/classes.rb +96 -0
  18. data/spec/fixtures/gets.txt +9 -0
  19. data/spec/fixtures/numbered_lines.txt +5 -0
  20. data/spec/fixtures/one_byte.txt +1 -0
  21. data/spec/fixtures/paragraphs.txt +7 -0
  22. data/spec/fixtures/readlines.txt +6 -0
  23. data/spec/flush_spec.rb +8 -0
  24. data/spec/getc_spec.rb +44 -0
  25. data/spec/gets_spec.rb +212 -0
  26. data/spec/isatty_spec.rb +6 -0
  27. data/spec/lineno_spec.rb +84 -0
  28. data/spec/output_spec.rb +47 -0
  29. data/spec/pos_spec.rb +53 -0
  30. data/spec/print_spec.rb +97 -0
  31. data/spec/printf_spec.rb +24 -0
  32. data/spec/putc_spec.rb +57 -0
  33. data/spec/puts_spec.rb +99 -0
  34. data/spec/read_spec.rb +162 -0
  35. data/spec/readchar_spec.rb +49 -0
  36. data/spec/readline_spec.rb +60 -0
  37. data/spec/readlines_spec.rb +140 -0
  38. data/spec/readpartial_spec.rb +92 -0
  39. data/spec/rewind_spec.rb +56 -0
  40. data/spec/seek_spec.rb +72 -0
  41. data/spec/shared/each.rb +204 -0
  42. data/spec/shared/eof.rb +116 -0
  43. data/spec/shared/pos.rb +39 -0
  44. data/spec/shared/tty.rb +12 -0
  45. data/spec/shared/write.rb +53 -0
  46. data/spec/sync_spec.rb +56 -0
  47. data/spec/sysread_spec.rb +87 -0
  48. data/spec/sysseek_spec.rb +68 -0
  49. data/spec/syswrite_spec.rb +60 -0
  50. data/spec/tell_spec.rb +7 -0
  51. data/spec/to_io_spec.rb +19 -0
  52. data/spec/tty_spec.rb +6 -0
  53. data/spec/ungetc_spec.rb +118 -0
  54. data/spec/write_spec.rb +61 -0
  55. data/spec_helper.rb +49 -0
  56. metadata +223 -32
  57. data/CONTRIBUTORS +0 -15
  58. data/GPL +0 -676
  59. data/HACKING +0 -123
  60. data/LEGAL +0 -56
  61. data/MANIFEST +0 -10
  62. data/README +0 -150
@@ -0,0 +1,7 @@
1
+ class MSpecScript
2
+ # An ordered list of the directories containing specs to run
3
+ set :files, ['spec']
4
+
5
+ # The default implementation to run the specs.
6
+ set :target, 'ruby'
7
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#binmode" do
5
+ before :each do
6
+ @filename = tmp("IO_binmode_file")
7
+ @file = File.open(@filename, "w")
8
+ @iowrapper = WritableIOWrapper.open(@file)
9
+ end
10
+
11
+ after :each do
12
+ @iowrapper.close unless @iowrapper.closed?
13
+ @file.close unless @file.closed?
14
+ File.delete(@filename) if File.exist?(@filename)
15
+ end
16
+
17
+ it "returns a reference to the stream" do
18
+ @iowrapper.binmode.should == @iowrapper
19
+ end
20
+
21
+ it "does not raise any errors on closed stream" do
22
+ lambda { IOSpecs.closed_file.binmode }.should_not raise_error()
23
+ end
24
+
25
+ # Even if it does nothing in Unix it should not raise any errors.
26
+ it "puts a stream in binary mode" do
27
+ lambda { @iowrapper.binmode }.should_not raise_error
28
+ end
29
+ end
@@ -0,0 +1,64 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+ require 'fileutils'
4
+
5
+ describe "IO::Like#close_read" do
6
+ before :each do
7
+ @io = IO.popen('cat', "r+")
8
+ @iowrapper = DuplexedIOWrapper.open(@io)
9
+ @filename = tmp('IO_Like__close_read_test')
10
+ end
11
+
12
+ after :each do
13
+ @iowrapper.close unless @iowrapper.closed?
14
+ @io.close unless @io.closed?
15
+ File.delete(@filename) if File.exist?(@filename)
16
+ end
17
+
18
+ it "closes the read end of a duplex I/O stream" do
19
+ @iowrapper.close_read
20
+
21
+ lambda { @iowrapper.read }.should raise_error(IOError)
22
+ end
23
+
24
+ it "raises an IOError on subsequent invocations" do
25
+ @iowrapper.close_read
26
+
27
+ lambda { @iowrapper.close_read }.should raise_error(IOError)
28
+ end
29
+
30
+ it "allows subsequent invocation of close" do
31
+ @iowrapper.close_read
32
+
33
+ lambda { @iowrapper.close }.should_not raise_error
34
+ end
35
+
36
+ it "raises an IOError if the stream is writable and not duplexed" do
37
+ io = File.open(@filename, 'w')
38
+ iowrapper = WritableIOWrapper.open(io)
39
+
40
+ begin
41
+ lambda { iowrapper.close_read }.should raise_error(IOError)
42
+ ensure
43
+ iowrapper.close unless iowrapper.closed?
44
+ io.close unless io.closed?
45
+ end
46
+ end
47
+
48
+ it "closes the stream if it is neither writable nor duplexed" do
49
+ FileUtils.touch(@filename)
50
+ io = File.open(@filename)
51
+ iowrapper = ReadableIOWrapper.open(io)
52
+
53
+ iowrapper.close_read
54
+ iowrapper.closed?.should == true
55
+
56
+ io.close
57
+ end
58
+
59
+ it "raises IOError on closed stream" do
60
+ @io.close
61
+
62
+ lambda { @io.close_read }.should raise_error(IOError)
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#close" do
5
+ before :each do
6
+ @filename = tmp('IO_Like__close_test')
7
+ @io = File.open(@filename, 'w+')
8
+ @iowrapper = IOWrapper.open(@io)
9
+ end
10
+
11
+ after :each do
12
+ @iowrapper.close unless @iowrapper.closed?
13
+ @io.close unless @io.closed?
14
+ File.unlink(@filename) if File.exist?(@filename)
15
+ end
16
+
17
+ it "closes the stream" do
18
+ lambda { @iowrapper.close }.should_not raise_error
19
+ @iowrapper.closed?.should == true
20
+ end
21
+
22
+ it "returns nil" do
23
+ @iowrapper.close.should == nil
24
+ end
25
+
26
+ it "makes the stream unavailable for any further data operations" do
27
+ @iowrapper.close
28
+ lambda { @iowrapper.write("attempt to write") }.should raise_error(IOError)
29
+ lambda { @iowrapper.read }.should raise_error(IOError)
30
+ end
31
+
32
+ it "raises an IOError on subsequent invocations" do
33
+ @iowrapper.close
34
+ lambda { @iowrapper.close }.should raise_error(IOError)
35
+ end
36
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#close_write" do
5
+ before :each do
6
+ @io = IO.popen('cat', 'r+')
7
+ @iowrapper = DuplexedIOWrapper.open(@io)
8
+ @filename = tmp('IO_Like__close_write_test')
9
+ end
10
+
11
+ after :each do
12
+ @iowrapper.close unless @iowrapper.closed?
13
+ @io.close unless @io.closed?
14
+ File.delete(@filename) if File.exist?(@filename)
15
+ end
16
+
17
+ it "closes the write end of a duplex I/O stream" do
18
+ @iowrapper.close_write
19
+ lambda { @iowrapper.write("attempt to write") }.should raise_error(IOError)
20
+ end
21
+
22
+ it "raises an IOError on subsequent invocations" do
23
+ @iowrapper.close_write
24
+ lambda { @iowrapper.close_write }.should raise_error(IOError)
25
+ end
26
+
27
+ it "allows subsequent invocation of close" do
28
+ @iowrapper.close_write
29
+ lambda { @iowrapper.close }.should_not raise_error
30
+ end
31
+
32
+ it "raises an IOError if the stream is readable and not duplexed" do
33
+ io = File.open(@filename, 'w+')
34
+ iowrapper = IOWrapper.open(io)
35
+
36
+ begin
37
+ lambda { iowrapper.close_write }.should raise_error(IOError)
38
+ ensure
39
+ iowrapper.close unless iowrapper.closed?
40
+ io.close unless io.closed?
41
+ end
42
+ end
43
+
44
+ it "closes the stream if it is neither readable nor duplexed" do
45
+ IOSpecs.writable_iowrapper do |iowrapper|
46
+ iowrapper.close_write
47
+ iowrapper.closed?.should == true
48
+ end
49
+ end
50
+
51
+ it "flushes and closes the write stream" do
52
+ @iowrapper.puts('12345')
53
+ @iowrapper.close_write
54
+ @io.close_write
55
+ @iowrapper.read.should == "12345\n"
56
+ end
57
+
58
+ it "raises IOError on closed stream" do
59
+ lambda { IOSpecs.closed_file.close_write }.should raise_error(IOError)
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#closed?" do
5
+ it "returns true on closed stream" do
6
+ IOSpecs.closed_file.closed?.should == true
7
+ end
8
+
9
+ it "returns false on open stream" do
10
+ File.open(File.dirname(__FILE__) + '/fixtures/gets.txt', 'r') do |io|
11
+ ReadableIOWrapper.open(io) do |iowrapper|
12
+ iowrapper.closed?.should == false
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#each_byte" do
5
+ it "raises IOError on closed stream" do
6
+ # each_byte must have a block in order to raise the Error.
7
+ # MRI 1.8.7 returns enumerator if block is not provided.
8
+ # See [ruby-core:16557].
9
+ lambda { IOSpecs.closed_file.each_byte {} }.should raise_error(IOError)
10
+ end
11
+
12
+ it "yields each byte" do
13
+ File.open(IOSpecs.gets_fixtures) do |io|
14
+ ReadableIOWrapper.open(io) do |iowrapper|
15
+ bytes = []
16
+
17
+ iowrapper.each_byte do |byte|
18
+ bytes << byte
19
+ break if bytes.length >= 5
20
+ end
21
+
22
+ bytes.should == [86, 111, 105, 99, 105]
23
+ end
24
+ end
25
+ end
26
+
27
+ it "works on empty streams" do
28
+ @filename = tmp("IO_Like__each_byte_test")
29
+ File.open(@filename, "w+") do |io|
30
+ IOWrapper.open(io) do |iowrapper|
31
+ lambda do
32
+ iowrapper.each_byte { |b| raise IOError }
33
+ end.should_not raise_error
34
+ end
35
+ end
36
+ File.unlink(@filename) if File.exist?(@filename)
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+ require File.dirname(__FILE__) + '/shared/each'
4
+
5
+ describe "IO::Like#each_line" do
6
+ it_behaves_like :io_like__each, :each_line
7
+ end
8
+
9
+ describe "IO::Like#each_line when passed a separator" do
10
+ it_behaves_like :io_like__each_separator, :each_line
11
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+ require File.dirname(__FILE__) + '/shared/each'
4
+
5
+ describe "IO::Like#each" do
6
+ it_behaves_like :io_like__each, :each
7
+ end
8
+
9
+ describe "IO::Like#each when passed a separator" do
10
+ it_behaves_like :io_like__each_separator, :each
11
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+ require File.dirname(__FILE__) + '/shared/eof'
4
+
5
+ describe "IO::Like#eof" do
6
+ it_behaves_like :io_like__eof, :eof
7
+ end
8
+
9
+ describe "IO::Like#eof?" do
10
+ it_behaves_like :io_like__eof, :eof?
11
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/../../lib/io/like'
2
+
3
+ class IOWrapper
4
+ include IO::Like
5
+
6
+ def self.open(io)
7
+ iow = new(io)
8
+ return iow unless block_given?
9
+
10
+ begin
11
+ yield(iow)
12
+ ensure
13
+ iow.close unless iow.closed?
14
+ end
15
+ end
16
+
17
+ def initialize(io)
18
+ @io = io
19
+ end
20
+
21
+ private
22
+
23
+ def unbuffered_read(length)
24
+ @io.sysread(length)
25
+ end
26
+
27
+ def unbuffered_seek(offset, whence = IO::SEEK_SET)
28
+ @io.sysseek(offset, whence)
29
+ end
30
+
31
+ def unbuffered_write(string)
32
+ @io.syswrite(string)
33
+ end
34
+ end
35
+
36
+ class DuplexedIOWrapper < IOWrapper
37
+ def duplexed?
38
+ true
39
+ end
40
+ end
41
+
42
+ class ReadableIOWrapper < IOWrapper
43
+ def writable?
44
+ false
45
+ end
46
+ end
47
+
48
+ class WritableIOWrapper < IOWrapper
49
+ def readable?
50
+ false
51
+ end
52
+ end
53
+
54
+ module IOSpecs
55
+ def self.lines
56
+ [
57
+ "Voici la ligne une.\n",
58
+ "Qui \303\250 la linea due.\n",
59
+ "\n",
60
+ "\n",
61
+ "Aqu\303\255 est\303\241 la l\303\255nea tres.\n",
62
+ "Ist hier Linie vier.\n",
63
+ "\n",
64
+ "Est\303\241 aqui a linha cinco.\n",
65
+ "Here is line six.\n"
66
+ ]
67
+ end
68
+
69
+ def self.gets_fixtures
70
+ File.dirname(__FILE__) + '/gets.txt'
71
+ end
72
+
73
+ def self.gets_output
74
+ File.dirname(__FILE__) + '/gets_output.txt'
75
+ end
76
+
77
+ def self.closed_file
78
+ File.open(gets_fixtures, 'r') do |f|
79
+ ReadableIOWrapper.open(f) { |iowrapper| iowrapper }
80
+ end
81
+ end
82
+
83
+ def self.readable_iowrapper(&b)
84
+ File.open(gets_fixtures, 'r') do |f|
85
+ ReadableIOWrapper.open(f, &b)
86
+ end
87
+ end
88
+
89
+ def self.writable_iowrapper(&b)
90
+ File.open(gets_output, 'w') do |f|
91
+ WritableIOWrapper.open(f, &b)
92
+ end
93
+ ensure
94
+ File.delete(gets_output)
95
+ end
96
+ end
@@ -0,0 +1,9 @@
1
+ Voici la ligne une.
2
+ Qui è la linea due.
3
+
4
+
5
+ Aquí está la línea tres.
6
+ Ist hier Linie vier.
7
+
8
+ Está aqui a linha cinco.
9
+ Here is line six.
@@ -0,0 +1,5 @@
1
+ Line 1: One
2
+ Line 2: Two
3
+ Line 3: Three
4
+ Line 4: Four
5
+ Line 5: Five
@@ -0,0 +1 @@
1
+ 1
@@ -0,0 +1,7 @@
1
+ This is
2
+
3
+ an example
4
+
5
+
6
+
7
+ of paragraphs.
@@ -0,0 +1,6 @@
1
+ Voici la ligne une.
2
+ Qui è la linea due.
3
+ Aquí está la línea tres.
4
+ Ist hier Linie vier.
5
+ Está aqui a linha cinco.
6
+ Here is line six.
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#flush" do
5
+ it "raises IOError on closed stream" do
6
+ lambda { IOSpecs.closed_file.flush }.should raise_error(IOError)
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/fixtures/classes'
3
+
4
+ describe "IO::Like#getc" do
5
+ before :each do
6
+ @file_name = File.dirname(__FILE__) + '/fixtures/readlines.txt'
7
+ @file = File.open(@file_name, 'r')
8
+ @iowrapper = ReadableIOWrapper.open(@file)
9
+ end
10
+
11
+ after :each do
12
+ @iowrapper.close unless @iowrapper.closed?
13
+ @file.close unless @file.closed?
14
+ end
15
+
16
+ it "returns the next byte from the stream" do
17
+ @iowrapper.getc.should == 86
18
+ @iowrapper.getc.should == 111
19
+ @iowrapper.getc.should == 105
20
+ # read the rest of line
21
+ @iowrapper.readline.should == "ci la ligne une.\n"
22
+ @iowrapper.getc.should == 81
23
+ end
24
+
25
+ it "returns nil when invoked at the end of the stream" do
26
+ # read entire content
27
+ @iowrapper.read
28
+ @iowrapper.getc.should == nil
29
+ end
30
+
31
+ it "returns nil on empty stream" do
32
+ path = tmp('empty.txt')
33
+ File.open(path, "w+") do |empty|
34
+ IOWrapper.open(empty) do |iowrapper|
35
+ iowrapper.getc.should == nil
36
+ end
37
+ end
38
+ File.unlink(path)
39
+ end
40
+
41
+ it "raises IOError on closed stream" do
42
+ lambda { IOSpecs.closed_file.getc }.should raise_error(IOError)
43
+ end
44
+ end