io-like 0.3.0 → 0.3.1

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