progressive_io 1.0.0 → 2.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +24 -0
- data/{README.rdoc → README.md} +41 -13
- data/Rakefile +8 -11
- data/lib/progressive_io.rb +133 -36
- data/test/test_progressive_io.rb +105 -46
- metadata +72 -67
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/History.txt +0 -6
- data/Manifest.txt +0 -7
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ea6428465be21d680077d7ed5077c9e8e8f0f72622249e3ccb2f585f38e7d969
|
4
|
+
data.tar.gz: f71c4577f2642efb23c3df42697cc52ce08a7cca603af89825efaf5c760c32b0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad62723654f1655d14b3a6b391581b1adcef7dbe27bf9a05901f405703118cb251b1bd4b4639ad3ce81d6099ba031596402ce16b96a54476ecdb2ddfa90cdba0
|
7
|
+
data.tar.gz: c1b87a837cb5f2a10defbf2dd1ec493b90b42db58f717b1aca2dfc6827af134fd223d4ca91e307ece53f0560e843fefc02b077f3cd72db47eed6e286f9a927e9
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## 2.0.1
|
2
|
+
|
3
|
+
* Revert back to using SimpleDelegator - it's just easier.
|
4
|
+
|
5
|
+
## 2.0.0
|
6
|
+
|
7
|
+
* Added comprehensive documentation with examples
|
8
|
+
* Added progress block support for tracking read operations
|
9
|
+
* Added support for StringIO and other IO-like objects
|
10
|
+
* Added each_byte method for byte-by-byte iteration with progress tracking
|
11
|
+
* Added getc method for single character reading with progress tracking
|
12
|
+
* Added gets method for line reading with progress tracking
|
13
|
+
* Modernized gem structure and build process
|
14
|
+
* Switched to Bundler for gem management
|
15
|
+
* Added Minitest test suite
|
16
|
+
* Increased minimum Ruby version requirement to 1.8.7
|
17
|
+
|
18
|
+
## 1.0.1
|
19
|
+
|
20
|
+
* Use Jeweler for build management
|
21
|
+
|
22
|
+
## 1.0.0
|
23
|
+
|
24
|
+
* First release
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,30 +1,58 @@
|
|
1
|
-
|
1
|
+
# progressive_io
|
2
2
|
|
3
3
|
* http://github.com/julik/progressive_io
|
4
4
|
|
5
|
-
|
5
|
+
## DESCRIPTION
|
6
6
|
|
7
|
-
A wrapper for IO objects that allows a callback to be set which is called when an object is read from
|
7
|
+
A wrapper for IO objects that allows a callback to be set which is called when an object is read from.
|
8
8
|
|
9
|
-
|
9
|
+
## FEATURES/PROBLEMS
|
10
10
|
|
11
11
|
* Wraps any IO
|
12
12
|
|
13
|
-
|
13
|
+
## SYNOPSIS
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
end
|
15
|
+
```ruby
|
16
|
+
require "progressive_io"
|
18
17
|
|
19
|
-
|
18
|
+
io = ProgressiveIO.new(File.open("/bigfile.dat")) do | pos |
|
19
|
+
puts "Read %d bytes" % [ pos ]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Then, elsewhere deep in the calling code...
|
23
|
+
io.each do | line | # Each yielded line will call the callback block
|
24
|
+
# Do stuff
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
For example, you can make any IO a provider for a [progressbar](http://rubygems.org/gem/progressbar):
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require "progressive_io"
|
32
|
+
require "progressbar"
|
33
|
+
|
34
|
+
# If you know the total size, you can create a progress bar
|
35
|
+
total_size = File.size("/bigfile.dat")
|
36
|
+
pbar = Progressbar.new("Pumping data", total_size)
|
37
|
+
io_with_progress = ProgressiveIO.new(File.open("/bigfile.dat")) { |pos| pbar.set(pos) }
|
38
|
+
|
39
|
+
# Then, elsewhere deep in the calling code...
|
40
|
+
io_with_progress.each do | line | # Each yielded line will call the callback block
|
41
|
+
# Each read operation will properly advance the progressbar
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
## REQUIREMENTS
|
20
46
|
|
21
47
|
* Ruby 1.8.6+
|
22
48
|
|
23
|
-
|
49
|
+
## INSTALL
|
24
50
|
|
25
|
-
|
51
|
+
```bash
|
52
|
+
gem install progressive_io
|
53
|
+
```
|
26
54
|
|
27
|
-
|
55
|
+
## LICENSE
|
28
56
|
|
29
57
|
(The MIT License)
|
30
58
|
|
@@ -47,4 +75,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
47
75
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
48
76
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
49
77
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
50
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
78
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
p.readme_file = 'README.rdoc'
|
9
|
-
p.extra_rdoc_files = FileList['*.rdoc'] + FileList['*.txt']
|
10
|
-
p.extra_dev_deps = {"flexmock" => "~> 0.8"}
|
11
|
-
p.clean_globs = File.read(File.dirname(__FILE__) + "/.gitignore").split(/\s/).to_a
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.pattern = "test/test_*.rb"
|
8
|
+
t.verbose = true
|
12
9
|
end
|
13
10
|
|
14
|
-
|
11
|
+
task :default => :test
|
data/lib/progressive_io.rb
CHANGED
@@ -1,86 +1,183 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require 'delegate'
|
4
|
+
|
5
|
+
# A wrapper class that provides progress tracking for IO operations.
|
6
|
+
#
|
7
|
+
# This class wraps an IO object and calls a progress block whenever data is read,
|
8
|
+
# allowing you to track reading progress for operations like file uploads or downloads.
|
9
|
+
#
|
10
|
+
# @example Basic usage with a file
|
11
|
+
# file = File.open('large_file.txt')
|
12
|
+
# progress_io = ProgressiveIO.new(file) do |current_pos|
|
13
|
+
# puts "Read #{current_pos} bytes"
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# progress_io.each_line do |line|
|
17
|
+
# # Process each line
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @example Usage with a StringIO
|
21
|
+
# string_io = StringIO.new("Hello\nWorld\n")
|
22
|
+
# progress_io = ProgressiveIO.new(string_io) do |current_pos|
|
23
|
+
# puts "Read #{current_pos} bytes"
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# content = progress_io.read
|
27
|
+
#
|
28
|
+
# @since 2.0.0
|
29
|
+
class ProgressiveIO < SimpleDelegator
|
30
|
+
# The version of the ProgressiveIO library
|
31
|
+
VERSION = '2.0.1'
|
5
32
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
attr_accessor :total_size
|
33
|
+
# @return [Proc, nil] The progress callback block that will be called when data is read
|
34
|
+
# The block receives one parameter: current position
|
9
35
|
attr_accessor :progress_block
|
10
36
|
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
37
|
+
# Creates a new ProgressiveIO wrapper around an IO object.
|
38
|
+
#
|
39
|
+
# @param with_io [IO] The IO object to wrap (File, StringIO, etc.)
|
40
|
+
# @param blk [Proc, nil] Optional block that will be called when data is read
|
41
|
+
# The block receives one parameter: current position
|
42
|
+
# @yield [current_pos] The progress callback
|
43
|
+
# @yieldparam current_pos [Integer] The current position in the IO stream
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# file = File.open('data.txt')
|
47
|
+
# progress_io = ProgressiveIO.new(file) do |pos|
|
48
|
+
# puts "Read #{pos} bytes"
|
49
|
+
# end
|
14
50
|
def initialize(with_io, &blk)
|
15
|
-
|
16
|
-
@total_size = with_io.stat.size if with_io.respond_to?(:stat)
|
51
|
+
super(with_io)
|
17
52
|
@progress_block = blk.to_proc if blk
|
18
53
|
end
|
19
54
|
|
20
|
-
#
|
55
|
+
# Iterates over the IO stream line by line, calling the progress block for each line.
|
56
|
+
#
|
57
|
+
# @param sep_string [String] The line separator (defaults to $/)
|
58
|
+
# @yield [line] Each line from the IO stream
|
59
|
+
# @yieldparam line [String] A line from the IO stream
|
60
|
+
# @return [Enumerator] An enumerator if no block is given
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# progress_io.each_line do |line|
|
64
|
+
# puts "Processing: #{line.chomp}"
|
65
|
+
# end
|
21
66
|
def each(sep_string = $/, &blk)
|
22
67
|
# Report offset at each call of the iterator
|
23
|
-
|
24
|
-
yield(line)
|
25
|
-
notify_read
|
68
|
+
super(sep_string) do |line|
|
69
|
+
yield(line).tap { notify_read }
|
26
70
|
end
|
27
71
|
end
|
28
72
|
alias_method :each_line, :each
|
29
73
|
|
74
|
+
# Iterates over the IO stream byte by byte, calling the progress block for each byte.
|
75
|
+
#
|
76
|
+
# @yield [byte] Each byte from the IO stream
|
77
|
+
# @yieldparam byte [Integer] A byte from the IO stream (0-255)
|
78
|
+
# @return [Enumerator] An enumerator if no block is given
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# progress_io.each_byte do |byte|
|
82
|
+
# puts "Byte: #{byte}"
|
83
|
+
# end
|
30
84
|
def each_byte(&blk)
|
31
85
|
# Report offset at each call of the iterator
|
32
|
-
super { |b| yield(b)
|
86
|
+
super { |b| yield(b).tap { notify_read } }
|
33
87
|
end
|
34
88
|
|
89
|
+
# Reads a single character from the IO stream.
|
90
|
+
#
|
91
|
+
# @return [String, nil] The next character or nil if at end of stream
|
92
|
+
# @see IO#getc
|
35
93
|
def getc
|
36
|
-
|
94
|
+
super.tap { notify_read }
|
37
95
|
end
|
38
96
|
|
39
|
-
|
40
|
-
|
97
|
+
# Reads a line from the IO stream.
|
98
|
+
#
|
99
|
+
# @param args [Array] Arguments to pass to the underlying IO#gets method
|
100
|
+
# @return [String, nil] The next line or nil if at end of stream
|
101
|
+
# @see IO#gets
|
102
|
+
def gets(*args)
|
103
|
+
super(*args).tap { notify_read }
|
41
104
|
end
|
42
105
|
|
106
|
+
# Reads data from the IO stream.
|
107
|
+
#
|
108
|
+
# @param a [Array] Arguments to pass to the underlying IO#read method
|
109
|
+
# @return [String, nil] The read data or nil if at end of stream
|
110
|
+
# @see IO#read
|
43
111
|
def read(*a)
|
44
|
-
|
112
|
+
super(*a).tap { notify_read }
|
45
113
|
end
|
46
114
|
|
115
|
+
# Reads a specific number of bytes from the IO stream.
|
116
|
+
#
|
117
|
+
# @param a [Array] Arguments to pass to the underlying IO#readbytes method
|
118
|
+
# @return [String] The read bytes
|
119
|
+
# @see IO#readbytes
|
47
120
|
def readbytes(*a)
|
48
|
-
|
121
|
+
super(*a).tap { notify_read }
|
49
122
|
end
|
50
123
|
|
124
|
+
# Reads a single character from the IO stream.
|
125
|
+
#
|
126
|
+
# @return [String] The next character
|
127
|
+
# @raise [EOFError] If at end of stream
|
128
|
+
# @see IO#readchar
|
51
129
|
def readchar
|
52
|
-
|
130
|
+
super.tap { notify_read }
|
53
131
|
end
|
54
132
|
|
133
|
+
# Reads a line from the IO stream.
|
134
|
+
#
|
135
|
+
# @param a [Array] Arguments to pass to the underlying IO#readline method
|
136
|
+
# @return [String] The next line
|
137
|
+
# @raise [EOFError] If at end of stream
|
138
|
+
# @see IO#readline
|
55
139
|
def readline(*a)
|
56
|
-
|
140
|
+
super(*a).tap { notify_read }
|
57
141
|
end
|
58
142
|
|
143
|
+
# Reads all lines from the IO stream.
|
144
|
+
#
|
145
|
+
# @param a [Array] Arguments to pass to the underlying IO#readlines method
|
146
|
+
# @return [Array<String>] Array of lines
|
147
|
+
# @see IO#readlines
|
59
148
|
def readlines(*a)
|
60
|
-
|
149
|
+
super(*a).tap { notify_read }
|
61
150
|
end
|
62
151
|
|
152
|
+
# Seeks to a position in the IO stream.
|
153
|
+
#
|
154
|
+
# @param a [Array] Arguments to pass to the underlying IO#seek method
|
155
|
+
# @return [Integer] The new position
|
156
|
+
# @see IO#seek
|
63
157
|
def seek(*a)
|
64
|
-
|
158
|
+
super(*a)
|
65
159
|
end
|
66
160
|
|
67
|
-
|
68
|
-
|
69
|
-
|
161
|
+
# def ungetc(*a)
|
162
|
+
# super(*a).tap { notify_read }
|
163
|
+
# end
|
70
164
|
|
165
|
+
# Sets the position in the IO stream.
|
166
|
+
#
|
167
|
+
# @param p [Integer] The new position
|
168
|
+
# @return [Integer] The new position
|
169
|
+
# @see IO#pos=
|
71
170
|
def pos=(p)
|
72
|
-
|
171
|
+
super(p).tap { notify_read }
|
73
172
|
end
|
74
173
|
|
75
174
|
private
|
76
|
-
# The "returning" idiom copied from ActiveSupport. We know that modern Rubies have
|
77
|
-
# Object#tap but why mandate newer Rubies for something as small as this?
|
78
|
-
def returning(r)
|
79
|
-
yield(r); r
|
80
|
-
end
|
81
175
|
|
82
|
-
#
|
176
|
+
# Calls the progress block with current position.
|
177
|
+
# This method is called whenever data is read from the IO stream.
|
178
|
+
#
|
179
|
+
# @return [void]
|
83
180
|
def notify_read
|
84
|
-
@progress_block.call(pos
|
181
|
+
@progress_block.call(pos) if @progress_block
|
85
182
|
end
|
86
183
|
end
|
data/test/test_progressive_io.rb
CHANGED
@@ -1,19 +1,10 @@
|
|
1
|
-
require "
|
2
|
-
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative "../lib/progressive_io"
|
3
3
|
require "flexmock"
|
4
|
-
require "flexmock/
|
4
|
+
require "flexmock/minitest"
|
5
5
|
require "stringio"
|
6
6
|
|
7
|
-
|
8
|
-
# https://github.com/jimweirich/flexmock/issues/4
|
9
|
-
# https://github.com/julik/flexmock/commit/4acea00677e7b558bd564ec7c7630f0b27d368ca
|
10
|
-
class FlexMock::PartialMockProxy
|
11
|
-
def singleton?(method_name)
|
12
|
-
@obj.singleton_methods.include?(method_name.to_s)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class TestProgressiveIO < Test::Unit::TestCase
|
7
|
+
class TestProgressiveIO < Minitest::Test
|
17
8
|
|
18
9
|
def e(s)
|
19
10
|
|
@@ -28,33 +19,33 @@ class TestProgressiveIO < Test::Unit::TestCase
|
|
28
19
|
def test_each
|
29
20
|
io, messages = e("Mary\nHad\nA little\nLamb"), []
|
30
21
|
|
31
|
-
io.progress_block = lambda do | offset
|
32
|
-
messages.push([offset
|
22
|
+
io.progress_block = lambda do | offset |
|
23
|
+
messages.push([offset])
|
33
24
|
end
|
34
25
|
|
35
26
|
lines = []
|
36
27
|
io.each {|line| lines.push(line) }
|
37
28
|
assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], lines
|
38
|
-
assert_equal [[5
|
29
|
+
assert_equal [[5], [9], [18], [22]], messages
|
39
30
|
end
|
40
31
|
|
41
32
|
def test_each_byte
|
42
33
|
io, messages = e("123"), []
|
43
34
|
|
44
|
-
io.progress_block = lambda do | offset
|
45
|
-
messages.push([offset
|
35
|
+
io.progress_block = lambda do | offset |
|
36
|
+
messages.push([offset])
|
46
37
|
end
|
47
38
|
|
48
39
|
bytes = []
|
49
40
|
io.each_byte{|s| bytes << s }
|
50
41
|
assert_equal [49, 50, 51], bytes
|
51
|
-
assert_equal [[1
|
42
|
+
assert_equal [[1], [2], [3]], messages
|
52
43
|
end
|
53
44
|
|
54
45
|
def test_getc
|
55
46
|
io = e("123")
|
56
|
-
io.progress_block = lambda do | offset
|
57
|
-
assert_equal
|
47
|
+
io.progress_block = lambda do | offset |
|
48
|
+
assert_equal 1, offset
|
58
49
|
end
|
59
50
|
if RUBY_VERSION < "1.9"
|
60
51
|
assert_equal 49, io.getc
|
@@ -63,26 +54,52 @@ class TestProgressiveIO < Test::Unit::TestCase
|
|
63
54
|
end
|
64
55
|
end
|
65
56
|
|
57
|
+
|
58
|
+
|
66
59
|
def test_gets
|
67
60
|
io = e("Mary\nHad\nA little\nLamb")
|
68
|
-
io.progress_block = lambda do | offset
|
69
|
-
assert_equal
|
61
|
+
io.progress_block = lambda do | offset |
|
62
|
+
assert_equal 5, offset
|
70
63
|
end
|
71
64
|
assert_equal "Mary\n", io.gets
|
72
65
|
end
|
73
66
|
|
67
|
+
def test_gets_with_separator
|
68
|
+
io = e("Mary\nHad\nA little\nLamb")
|
69
|
+
io.progress_block = lambda do | offset |
|
70
|
+
assert_equal 4, offset
|
71
|
+
end
|
72
|
+
assert_equal "Mary", io.gets("y")
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_gets_with_limit
|
76
|
+
io = e("Mary\nHad\nA little\nLamb")
|
77
|
+
io.progress_block = lambda do | offset |
|
78
|
+
assert_equal 3, offset
|
79
|
+
end
|
80
|
+
assert_equal "Mar", io.gets(3)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_gets_with_separator_and_limit
|
84
|
+
io = e("Mary\nHad\nA little\nLamb")
|
85
|
+
io.progress_block = lambda do | offset |
|
86
|
+
assert_equal 2, offset
|
87
|
+
end
|
88
|
+
assert_equal "Ma", io.gets("a", 2)
|
89
|
+
end
|
90
|
+
|
74
91
|
def test_read
|
75
92
|
io = e("Mary\nHad\nA little\nLamb")
|
76
|
-
io.progress_block = lambda do | offset
|
77
|
-
assert_equal
|
93
|
+
io.progress_block = lambda do | offset |
|
94
|
+
assert_equal 15, offset
|
78
95
|
end
|
79
96
|
assert_equal "Mary\nHad\nA litt", io.read(15)
|
80
97
|
end
|
81
98
|
|
82
99
|
def test_readchar
|
83
100
|
io = e("123")
|
84
|
-
io.progress_block = lambda do | offset
|
85
|
-
assert_equal
|
101
|
+
io.progress_block = lambda do | offset |
|
102
|
+
assert_equal 1, offset
|
86
103
|
end
|
87
104
|
|
88
105
|
if RUBY_VERSION < "1.9"
|
@@ -92,50 +109,92 @@ class TestProgressiveIO < Test::Unit::TestCase
|
|
92
109
|
end
|
93
110
|
end
|
94
111
|
|
112
|
+
|
113
|
+
|
95
114
|
def test_readline
|
96
115
|
io = e("Mary\nHad\nA little\nLamb")
|
97
|
-
io.progress_block = lambda do | offset
|
98
|
-
assert_equal
|
116
|
+
io.progress_block = lambda do | offset |
|
117
|
+
assert_equal 5, offset
|
99
118
|
end
|
100
119
|
assert_equal "Mary\n", io.readline
|
101
120
|
end
|
102
121
|
|
122
|
+
def test_readline_with_separator
|
123
|
+
io = e("Mary\nHad\nA little\nLamb")
|
124
|
+
io.progress_block = lambda do | offset |
|
125
|
+
assert_equal 4, offset
|
126
|
+
end
|
127
|
+
assert_equal "Mary", io.readline("y")
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_readline_with_limit
|
131
|
+
io = e("Mary\nHad\nA little\nLamb")
|
132
|
+
io.progress_block = lambda do | offset |
|
133
|
+
assert_equal 3, offset
|
134
|
+
end
|
135
|
+
assert_equal "Mar", io.readline(3)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_readline_with_separator_and_limit
|
139
|
+
io = e("Mary\nHad\nA little\nLamb")
|
140
|
+
io.progress_block = lambda do | offset |
|
141
|
+
assert_equal 2, offset
|
142
|
+
end
|
143
|
+
assert_equal "Ma", io.readline("a", 2)
|
144
|
+
end
|
145
|
+
|
103
146
|
def test_readlines
|
104
147
|
io = e("Mary\nHad\nA little\nLamb")
|
105
148
|
m = []
|
106
|
-
io.progress_block = lambda do | offset
|
107
|
-
m.push([offset
|
149
|
+
io.progress_block = lambda do | offset |
|
150
|
+
m.push([offset])
|
108
151
|
end
|
109
152
|
|
110
153
|
assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], io.readlines
|
111
|
-
assert_equal [[22
|
154
|
+
assert_equal [[22]], m
|
112
155
|
end
|
113
156
|
|
114
|
-
def
|
157
|
+
def test_readlines_with_separator
|
115
158
|
io = e("Mary\nHad\nA little\nLamb")
|
116
|
-
|
117
|
-
|
159
|
+
m = []
|
160
|
+
io.progress_block = lambda do | offset |
|
161
|
+
m.push([offset])
|
118
162
|
end
|
119
|
-
|
163
|
+
|
164
|
+
assert_equal ["Mary\nHad\nA little", "\nLamb"], io.readlines("e")
|
165
|
+
assert_equal [[22]], m
|
120
166
|
end
|
121
167
|
|
122
|
-
def
|
168
|
+
def test_seek
|
123
169
|
io = e("Mary\nHad\nA little\nLamb")
|
124
|
-
|
125
|
-
|
126
|
-
m.push([offset, total])
|
170
|
+
io.progress_block = lambda do | offset |
|
171
|
+
assert_equal 6, offset
|
127
172
|
end
|
128
|
-
|
129
|
-
io.getc
|
130
|
-
io.ungetc(2)
|
131
|
-
assert_equal [[1, 22], [0, 22]], m
|
173
|
+
io.seek(6)
|
132
174
|
end
|
133
175
|
|
176
|
+
# def test_ungetc
|
177
|
+
# io = e("Mary\nHad\nA little\nLamb")
|
178
|
+
# m = []
|
179
|
+
# io.progress_block = lambda do | offset |
|
180
|
+
# m.push([offset])
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# char = io.getc
|
184
|
+
# io.ungetc("a")
|
185
|
+
# assert_equal [[1], [0]], m
|
186
|
+
# end
|
187
|
+
|
134
188
|
def test_poseq
|
135
189
|
io = e("Mary\nHad\nA little\nLamb")
|
136
|
-
|
137
|
-
|
190
|
+
m = []
|
191
|
+
io.progress_block = lambda do | offset |
|
192
|
+
m << [offset]
|
138
193
|
end
|
139
194
|
io.pos = 2
|
195
|
+
io.pos = 3
|
196
|
+
io.pos = 4
|
197
|
+
|
198
|
+
assert_equal [[2], [3], [4]], m
|
140
199
|
end
|
141
200
|
end
|
metadata
CHANGED
@@ -1,86 +1,91 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: progressive_io
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 1.0.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.1
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Julik Tarkhanov
|
9
|
-
autorequire:
|
10
8
|
bindir: bin
|
11
9
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
date: 2025-08-01 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rake
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.0'
|
19
|
+
type: :development
|
17
20
|
prerelease: false
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: flexmock
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.8'
|
24
33
|
type: :development
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: hoe
|
28
34
|
prerelease: false
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.8'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: minitest
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '5.0'
|
35
47
|
type: :development
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
-
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.0'
|
54
|
+
description: A Ruby gem that provides an IO wrapper with progress reporting capabilities.
|
55
|
+
It wraps any IO object and calls a callback with the current offset and total size
|
56
|
+
on each read operation, making it perfect for implementing progress bars or monitoring
|
57
|
+
file operations.
|
58
|
+
email: me@julik.nl
|
40
59
|
executables: []
|
41
|
-
|
42
60
|
extensions: []
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
-
|
47
|
-
- README.
|
48
|
-
files:
|
49
|
-
- .autotest
|
50
|
-
- History.txt
|
51
|
-
- Manifest.txt
|
52
|
-
- README.rdoc
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.md
|
63
|
+
files:
|
64
|
+
- CHANGELOG.md
|
65
|
+
- README.md
|
53
66
|
- Rakefile
|
54
67
|
- lib/progressive_io.rb
|
55
68
|
- test/test_progressive_io.rb
|
56
|
-
- .gemtest
|
57
69
|
homepage: http://github.com/julik/progressive_io
|
58
|
-
licenses:
|
59
|
-
|
60
|
-
|
61
|
-
rdoc_options:
|
62
|
-
|
63
|
-
- README.rdoc
|
64
|
-
require_paths:
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
65
75
|
- lib
|
66
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
-
|
68
|
-
requirements:
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
69
78
|
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version:
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
-
|
74
|
-
requirements:
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.8.7
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
75
83
|
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version:
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
78
86
|
requirements: []
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
summary: A wrapper for IO objects that allows a callback to be set which is called when an object is read from
|
85
|
-
test_files:
|
86
|
-
- test/test_progressive_io.rb
|
87
|
+
rubygems_version: 3.6.6
|
88
|
+
specification_version: 4
|
89
|
+
summary: An IO wrapper that sends reports on the offset to a callback, on each read
|
90
|
+
operation
|
91
|
+
test_files: []
|
data/.autotest
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
|
-
require 'autotest/restart'
|
4
|
-
|
5
|
-
# Autotest.add_hook :initialize do |at|
|
6
|
-
# at.extra_files << "../some/external/dependency.rb"
|
7
|
-
#
|
8
|
-
# at.libs << ":../some/external"
|
9
|
-
#
|
10
|
-
# at.add_exception 'vendor'
|
11
|
-
#
|
12
|
-
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
-
# at.files_matching(/test_.*rb$/)
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# %w(TestA TestB).each do |klass|
|
17
|
-
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
|
21
|
-
# Autotest.add_hook :run_command do |at|
|
22
|
-
# system "rake build"
|
23
|
-
# end
|
data/.gemtest
DELETED
File without changes
|
data/History.txt
DELETED