spinning_cursor 0.1.2 → 0.2.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.
- data/CHANGELOG +16 -1
- data/Gemfile +3 -3
- data/Gemfile.lock +60 -15
- data/README.md +14 -3
- data/TODO +2 -1
- data/VERSION +1 -1
- data/lib/spinning_cursor.rb +45 -63
- data/lib/spinning_cursor/console_helpers.rb +88 -0
- data/lib/spinning_cursor/cursor.rb +30 -46
- data/lib/spinning_cursor/parser.rb +29 -22
- data/lib/spinning_cursor/stop_watch.rb +78 -0
- data/spinning_cursor.gemspec +13 -11
- data/test/helper.rb +17 -2
- data/test/test_cursors.rb +61 -21
- data/test/test_exceptions.rb +0 -6
- data/test/test_parser.rb +56 -12
- data/test/test_spinning_cursor.rb +74 -9
- metadata +13 -11
data/CHANGELOG
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
===============================================================================
|
3
3
|
|
4
|
+
v0.2.0 (2013-07-13)
|
5
|
+
- Several bug fixes/internal API improvements (#4 #8 #9 #10 #11 #13)
|
6
|
+
- Suppress output from action block (#7)
|
7
|
+
- Add `output` option to display inline or all at once at the end (#13)
|
8
|
+
- Add `delay` option to specify cursor speed (#2)
|
9
|
+
- Hide terminal cursor during cursor animation (#11)
|
10
|
+
- Better exception handling (#13)
|
11
|
+
|
12
|
+
|
13
|
+
v0.1.1 - v0.1.2 (2012-04-25)
|
14
|
+
- Task timing is more concentrated (times, yields, works out the difference)
|
15
|
+
- Trying to set the message/banner after a task has finished raises an
|
16
|
+
exception
|
17
|
+
- Exceptions are showing now (promise this time D;)
|
18
|
+
|
4
19
|
v0.1.0 (2012-04-10)
|
5
20
|
- First non-pre release
|
6
21
|
- Exceptions in the task cause the cursor to stop and the exception is shown
|
@@ -15,4 +30,4 @@ v0.1.0.rc1 (2012-04-09)
|
|
15
30
|
- Set the loading message, type of spinner and finished message
|
16
31
|
- Pass in an action block to do the whole start stop loop, or don't and
|
17
32
|
call stop yourself
|
18
|
-
- Change the finish message within your task block
|
33
|
+
- Change the finish message within your task block
|
data/Gemfile
CHANGED
@@ -7,9 +7,9 @@ source "http://rubygems.org"
|
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
9
|
gem "shoulda", ">= 0"
|
10
|
-
gem "bundler", "~> 1.
|
11
|
-
gem "jeweler", "~> 1.8.
|
12
|
-
gem "yard"
|
10
|
+
gem "bundler", "~> 1.3.5"
|
11
|
+
gem "jeweler", "~> 1.8.4"
|
12
|
+
gem "yard", "~> 0.8.6.2"
|
13
13
|
gem "redcarpet"
|
14
14
|
gem "github-markup"
|
15
15
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,32 +1,77 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
activesupport (4.0.0)
|
5
|
+
i18n (~> 0.6, >= 0.6.4)
|
6
|
+
minitest (~> 4.2)
|
7
|
+
multi_json (~> 1.3)
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
tzinfo (~> 0.3.37)
|
10
|
+
addressable (2.3.5)
|
11
|
+
atomic (1.1.10)
|
12
|
+
builder (3.2.2)
|
13
|
+
faraday (0.8.7)
|
14
|
+
multipart-post (~> 1.1)
|
4
15
|
git (1.2.5)
|
5
|
-
github-markup (0.7.
|
6
|
-
|
16
|
+
github-markup (0.7.5)
|
17
|
+
github_api (0.10.1)
|
18
|
+
addressable
|
19
|
+
faraday (~> 0.8.1)
|
20
|
+
hashie (>= 1.2)
|
21
|
+
multi_json (~> 1.4)
|
22
|
+
nokogiri (~> 1.5.2)
|
23
|
+
oauth2
|
24
|
+
hashie (2.0.5)
|
25
|
+
highline (1.6.19)
|
26
|
+
httpauth (0.2.0)
|
27
|
+
i18n (0.6.4)
|
28
|
+
jeweler (1.8.6)
|
29
|
+
builder
|
7
30
|
bundler (~> 1.0)
|
8
31
|
git (>= 1.2.5)
|
32
|
+
github_api (= 0.10.1)
|
33
|
+
highline (>= 1.6.15)
|
34
|
+
nokogiri (= 1.5.10)
|
9
35
|
rake
|
10
36
|
rdoc
|
11
|
-
json (1.
|
12
|
-
|
13
|
-
|
37
|
+
json (1.8.0)
|
38
|
+
jwt (0.1.8)
|
39
|
+
multi_json (>= 1.5)
|
40
|
+
minitest (4.7.5)
|
41
|
+
multi_json (1.7.7)
|
42
|
+
multi_xml (0.5.4)
|
43
|
+
multipart-post (1.2.0)
|
44
|
+
nokogiri (1.5.10)
|
45
|
+
oauth2 (0.9.2)
|
46
|
+
faraday (~> 0.8)
|
47
|
+
httpauth (~> 0.2)
|
48
|
+
jwt (~> 0.1.4)
|
49
|
+
multi_json (~> 1.0)
|
50
|
+
multi_xml (~> 0.5)
|
51
|
+
rack (~> 1.2)
|
52
|
+
rack (1.5.2)
|
53
|
+
rake (10.1.0)
|
54
|
+
rdoc (4.0.1)
|
14
55
|
json (~> 1.4)
|
15
|
-
redcarpet (
|
16
|
-
shoulda (3.0
|
17
|
-
shoulda-context (~> 1.0.0)
|
18
|
-
shoulda-matchers (
|
19
|
-
shoulda-context (1.
|
20
|
-
shoulda-matchers (
|
21
|
-
|
56
|
+
redcarpet (3.0.0)
|
57
|
+
shoulda (3.5.0)
|
58
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
59
|
+
shoulda-matchers (>= 1.4.1, < 3.0)
|
60
|
+
shoulda-context (1.1.4)
|
61
|
+
shoulda-matchers (2.2.0)
|
62
|
+
activesupport (>= 3.0.0)
|
63
|
+
thread_safe (0.1.0)
|
64
|
+
atomic
|
65
|
+
tzinfo (0.3.37)
|
66
|
+
yard (0.8.6.2)
|
22
67
|
|
23
68
|
PLATFORMS
|
24
69
|
ruby
|
25
70
|
|
26
71
|
DEPENDENCIES
|
27
|
-
bundler (~> 1.
|
72
|
+
bundler (~> 1.3.5)
|
28
73
|
github-markup
|
29
|
-
jeweler (~> 1.8.
|
74
|
+
jeweler (~> 1.8.4)
|
30
75
|
redcarpet
|
31
76
|
shoulda
|
32
|
-
yard
|
77
|
+
yard (~> 0.8.6.2)
|
data/README.md
CHANGED
@@ -56,6 +56,11 @@ It's as easy as that!
|
|
56
56
|
* `action` - The stuff you want to do whilst the cursor is spinning.
|
57
57
|
* `message` - The message you want to show the user once the task is finished.
|
58
58
|
Defaults to "Done".
|
59
|
+
* `delay` - Sets the delay in seconds between the frames of the animation.
|
60
|
+
Defaults depend on type of cursor animation (spinner 0.5s, dots 1s)
|
61
|
+
* `output` - Sets how to display program output during cursor animation
|
62
|
+
(`:inline` or `:at_stop`).
|
63
|
+
Defaults to `:inline`.
|
59
64
|
|
60
65
|
### But the action block would get too messy!
|
61
66
|
|
@@ -82,7 +87,7 @@ SpinningCursor.stop
|
|
82
87
|
```
|
83
88
|
|
84
89
|
**Notice** the absence of the `action` option. The start method will only keep
|
85
|
-
the cursor running if an `action` block isn't passed
|
90
|
+
the cursor running if an `action` block isn't passed to it.
|
86
91
|
|
87
92
|
### I want to be able to change the finish message conditionally!
|
88
93
|
|
@@ -147,7 +152,7 @@ The hash contains the following, self-explanatory keys:
|
|
147
152
|
#### Suggestions
|
148
153
|
|
149
154
|
There isn't much this library should do, but a good suggestion is always
|
150
|
-
welcome. Make sure to use the issue
|
155
|
+
welcome. Make sure to use the issue tracker on GitHub to make suggestions -- and
|
151
156
|
fork & pull request if you want to implement it yourself, of course.
|
152
157
|
|
153
158
|
#### More Cursors!
|
@@ -166,7 +171,7 @@ indebted to you. It's a learning experience for me!
|
|
166
171
|
|
167
172
|
* Check out the latest master to make sure the feature hasn't been implemented
|
168
173
|
or the bug hasn't been fixed yet.
|
169
|
-
* Check out the issue tracker to make sure someone
|
174
|
+
* Check out the issue tracker to make sure someone hasn't already requested it
|
170
175
|
and/or contributed it.
|
171
176
|
* Fork the project.
|
172
177
|
* Start a feature/bugfix branch.
|
@@ -177,3 +182,9 @@ indebted to you. It's a learning experience for me!
|
|
177
182
|
to have your own version, or is otherwise necessary, that is fine, but
|
178
183
|
please isolate to its own commit so I can cherry-pick around it.
|
179
184
|
|
185
|
+
### List of contributors
|
186
|
+
|
187
|
+
A massive thanks to those who have taken some time out to help improve
|
188
|
+
Spinning Cursor!
|
189
|
+
|
190
|
+
* Abinoam P. Marques Jr. (@abinoam)
|
data/TODO
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
Suppress output and show later?
|
1
|
+
Suppress output and show later? (give option to produce log file, or just print it to the screen after it's finished),
|
2
|
+
default to hide though.
|
2
3
|
deal with returns?
|
3
4
|
test changes to spinning cursor, check diff for changes
|
4
5
|
refactor tests to use minitest
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/spinning_cursor.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
+
require "spinning_cursor/console_helpers"
|
1
2
|
require "spinning_cursor/cursor"
|
2
3
|
require "spinning_cursor/parser"
|
4
|
+
require "spinning_cursor/stop_watch"
|
3
5
|
|
4
6
|
module SpinningCursor
|
5
7
|
extend self
|
8
|
+
include self::ConsoleHelpers
|
9
|
+
extend self::ConsoleHelpers
|
6
10
|
|
7
11
|
#
|
8
12
|
# Sends passed block to Parser, and starts cursor thread
|
@@ -10,30 +14,36 @@ module SpinningCursor
|
|
10
14
|
# thread if an action block is passed.
|
11
15
|
#
|
12
16
|
def start(&block)
|
13
|
-
if
|
14
|
-
if @curs.alive?
|
15
|
-
stop
|
16
|
-
end
|
17
|
-
end
|
17
|
+
stop if alive?
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
save_stdout_sync_status
|
20
|
+
capture_console
|
21
|
+
hide_cursor
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
@parsed = Parser.new(&block)
|
24
|
+
@cursor = Cursor.new(@parsed)
|
25
|
+
@spinner = Thread.new do
|
26
|
+
abort_on_exception = true
|
27
|
+
@cursor.spin
|
27
28
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
|
30
|
+
@stop_watch = StopWatch.new
|
31
|
+
|
32
|
+
if @parsed.action
|
33
|
+
# The action
|
34
|
+
begin
|
35
|
+
@stop_watch.measure do
|
36
|
+
@parsed.outer_scope_object.instance_eval &@parsed.action
|
37
|
+
end
|
38
|
+
rescue StandardError => e
|
39
|
+
set_message "#{e.message}\n#{e.backtrace.join("\n")}"
|
40
|
+
raise
|
41
|
+
ensure
|
42
|
+
stop
|
32
43
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
return stop
|
44
|
+
else
|
45
|
+
# record start time
|
46
|
+
@stop_watch.start
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
@@ -43,20 +53,28 @@ module SpinningCursor
|
|
43
53
|
#
|
44
54
|
def stop
|
45
55
|
begin
|
46
|
-
|
56
|
+
restore_stdout_sync_status
|
57
|
+
if console_captured?
|
58
|
+
$console.print ESC_R_AND_CLR + $stdout.string
|
59
|
+
release_console
|
60
|
+
end
|
61
|
+
show_cursor
|
62
|
+
|
63
|
+
@spinner.kill
|
47
64
|
# Wait for the cursor to die -- can cause problems otherwise
|
48
|
-
|
65
|
+
@spinner.join
|
49
66
|
# Set cursor to nil so set_banner method only works
|
50
67
|
# when cursor is actually running.
|
51
68
|
@cursor = nil
|
52
69
|
reset_line
|
53
|
-
puts
|
70
|
+
puts @parsed.message
|
54
71
|
# Set parsed to nil so set_message method only works
|
55
72
|
# when cursor is actually running.
|
56
73
|
@parsed = nil
|
57
74
|
|
58
75
|
# Return execution time
|
59
|
-
|
76
|
+
@stop_watch.stop
|
77
|
+
@stop_watch.timing
|
60
78
|
rescue NameError
|
61
79
|
raise CursorNotRunning.new "Can't stop, no cursor running."
|
62
80
|
end
|
@@ -66,11 +84,7 @@ module SpinningCursor
|
|
66
84
|
# Determines whether the cursor thread is still running
|
67
85
|
#
|
68
86
|
def alive?
|
69
|
-
|
70
|
-
return false
|
71
|
-
else
|
72
|
-
@curs.alive?
|
73
|
-
end
|
87
|
+
@spinner and @spinner.alive?
|
74
88
|
end
|
75
89
|
|
76
90
|
#
|
@@ -91,47 +105,15 @@ module SpinningCursor
|
|
91
105
|
#
|
92
106
|
def set_banner(banner)
|
93
107
|
begin
|
94
|
-
@
|
108
|
+
@parsed.banner banner
|
95
109
|
rescue NameError
|
96
110
|
raise CursorNotRunning.new "Cursor isn't running... are you sure " +
|
97
111
|
"you're calling this from an action block?"
|
98
112
|
end
|
99
113
|
end
|
100
114
|
|
101
|
-
#
|
102
|
-
# Retrieves execution time information
|
103
|
-
#
|
104
|
-
def get_exec_time
|
105
|
-
if not @start.nil?
|
106
|
-
if @finish.nil? && @curs.alive? == false
|
107
|
-
do_exec_time
|
108
|
-
end
|
109
|
-
return { :started => @start, :finished => @finish,
|
110
|
-
:elapsed => @elapsed }
|
111
|
-
else
|
112
|
-
raise NoTaskError.new "An execution hasn't started or finished."
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
115
|
private
|
117
116
|
|
118
|
-
#
|
119
|
-
# Takes a block, and returns the start, finish and elapsed times
|
120
|
-
#
|
121
|
-
def do_exec_time
|
122
|
-
if @curs.alive?
|
123
|
-
@start = Time.now
|
124
|
-
if block_given?
|
125
|
-
yield
|
126
|
-
@finish = Time.now
|
127
|
-
@elapsed = @finish - @start
|
128
|
-
end
|
129
|
-
else
|
130
|
-
@finish = Time.now
|
131
|
-
@elapsed = @finish - @start
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
117
|
class NoTaskError < Exception ; end
|
136
118
|
class CursorNotRunning < NoTaskError ; end
|
137
|
-
end
|
119
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
$console = STDOUT
|
4
|
+
|
5
|
+
module SpinningCursor
|
6
|
+
module ConsoleHelpers
|
7
|
+
if RUBY_PLATFORM =~ /(win|w)32$/
|
8
|
+
# DOS
|
9
|
+
# Contains a string to clear the line in the shell
|
10
|
+
CLR = " \r"
|
11
|
+
else
|
12
|
+
# Unix
|
13
|
+
# Contains a string to clear the line in the shell
|
14
|
+
CLR = "\e[0K"
|
15
|
+
end
|
16
|
+
|
17
|
+
# ANSI escape sequence for hiding terminal cursor
|
18
|
+
ESC_CURS_INVIS = "\e[?25l"
|
19
|
+
# ANSI escape sequence for showing terminal cursor
|
20
|
+
ESC_CURS_VIS = "\e[?25h"
|
21
|
+
# ANSI escape sequence for clearing line in terminal
|
22
|
+
ESC_R_AND_CLR = "\r#{CLR}"
|
23
|
+
|
24
|
+
#
|
25
|
+
# Manages line reset in the console
|
26
|
+
#
|
27
|
+
def reset_line(text = "")
|
28
|
+
$console.print "#{ESC_R_AND_CLR}#{text}"
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Stores current `STDOUT.sync` value and sets it to true
|
33
|
+
#
|
34
|
+
def save_stdout_sync_status
|
35
|
+
@stdout_sync_saved_status = STDOUT.sync
|
36
|
+
STDOUT.sync = true
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Restores the previously stored `STDOUT.sync` value
|
41
|
+
#
|
42
|
+
def restore_stdout_sync_status
|
43
|
+
STDOUT.sync = @stdout_sync_saved_status
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Sets `$stdout` global variable to a `StringIO` object to buffer output
|
48
|
+
#
|
49
|
+
def capture_console
|
50
|
+
$stdout = StringIO.new
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Resets `$stdout` global variable to `STDOUT`
|
55
|
+
#
|
56
|
+
def release_console
|
57
|
+
$stdout = $console
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Returns true if `$stdout` is a `StringIO` object
|
62
|
+
#
|
63
|
+
def console_captured?
|
64
|
+
$stdout.is_a?(StringIO)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Returns true if the output buffer is currently empty
|
69
|
+
#
|
70
|
+
def captured_console_empty?
|
71
|
+
console_captured? and $stdout.string.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Hides the terminal cursor
|
76
|
+
#
|
77
|
+
def hide_cursor
|
78
|
+
$console.print ESC_CURS_INVIS
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Shows the terminal cursor
|
83
|
+
#
|
84
|
+
def show_cursor
|
85
|
+
$console.print ESC_CURS_VIS
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,43 +1,30 @@
|
|
1
1
|
module SpinningCursor
|
2
|
-
if RUBY_PLATFORM =~ /(win|w)32$/
|
3
|
-
# DOS
|
4
|
-
# Contains a string to clear the line in the shell
|
5
|
-
CLR = " \r"
|
6
|
-
else
|
7
|
-
# Unix
|
8
|
-
# Contains a string to clear the line in the shell
|
9
|
-
CLR = "\e[0K"
|
10
|
-
end
|
11
|
-
|
12
|
-
#
|
13
|
-
# Manages line reset in the console
|
14
|
-
#
|
15
|
-
def reset_line(text = "")
|
16
|
-
print "\r#{CLR}#{text}"
|
17
|
-
end
|
18
|
-
|
19
2
|
#
|
20
3
|
# This class contains the cursor types (and their helper methods)
|
21
4
|
#
|
22
5
|
class Cursor
|
23
|
-
|
6
|
+
include SpinningCursor::ConsoleHelpers
|
24
7
|
|
25
8
|
#
|
26
9
|
# As of v0.1.0: only initializes the cursor class, use the spin
|
27
10
|
# method to start the printing. Takes only the banner argument as
|
28
11
|
# a result of this.
|
29
12
|
#
|
30
|
-
def initialize(
|
31
|
-
@
|
13
|
+
def initialize(parsed)
|
14
|
+
@parsed = parsed
|
32
15
|
end
|
33
16
|
|
34
17
|
#
|
35
|
-
# Takes a cursor type symbol and starts the printing
|
18
|
+
# Takes a cursor type symbol and delay, and starts the printing
|
36
19
|
#
|
37
|
-
def spin
|
20
|
+
def spin
|
38
21
|
$stdout.sync = true
|
39
|
-
print @banner
|
40
|
-
|
22
|
+
$console.print @parsed.banner
|
23
|
+
if @parsed.delay
|
24
|
+
send @parsed.type, @parsed.delay
|
25
|
+
else
|
26
|
+
send @parsed.type
|
27
|
+
end
|
41
28
|
end
|
42
29
|
|
43
30
|
private
|
@@ -45,33 +32,30 @@ module SpinningCursor
|
|
45
32
|
#
|
46
33
|
# Prints three dots and clears the line
|
47
34
|
#
|
48
|
-
def dots
|
49
|
-
|
50
|
-
loop do
|
51
|
-
sleep 1
|
52
|
-
if i % 4 == 0
|
53
|
-
SpinningCursor.reset_line @banner
|
54
|
-
i += 1
|
55
|
-
next
|
56
|
-
end
|
57
|
-
i += 1
|
58
|
-
print "."
|
59
|
-
end
|
35
|
+
def dots(delay = 1)
|
36
|
+
cycle_through ['.', '..', '...', ''], delay
|
60
37
|
end
|
61
38
|
|
62
39
|
#
|
63
40
|
# Cycles through '|', '/', '-', '\', resembling a spinning cursor
|
64
41
|
#
|
65
|
-
def spinner
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
42
|
+
def spinner(delay = 0.5)
|
43
|
+
cycle_through ['|', '/', '-', '\\'], delay
|
44
|
+
end
|
45
|
+
|
46
|
+
def cycle_through(chars, delay)
|
47
|
+
chars.cycle do |char|
|
48
|
+
unless @parsed.output==:at_stop or captured_console_empty?
|
49
|
+
$console.print "#{ESC_R_AND_CLR}"
|
50
|
+
$console.print $stdout.string
|
51
|
+
$console.print "\n" unless $stdout.string[-1,1] == "\n"
|
52
|
+
$stdout.string = "" # TODO: Check for race condition.
|
53
|
+
end
|
54
|
+
$console.print "#{ESC_R_AND_CLR}#{@parsed.banner}"
|
55
|
+
$console.print " " unless @parsed.banner.empty?
|
56
|
+
$console.print "#{char}"
|
57
|
+
sleep delay
|
74
58
|
end
|
75
59
|
end
|
76
60
|
end
|
77
|
-
end
|
61
|
+
end
|
@@ -1,43 +1,50 @@
|
|
1
1
|
module SpinningCursor
|
2
2
|
class Parser
|
3
|
-
|
3
|
+
attr_accessor :outer_scope_object
|
4
4
|
|
5
5
|
#
|
6
6
|
# Parses proc
|
7
7
|
#
|
8
|
-
def initialize(
|
9
|
-
@banner
|
10
|
-
@type
|
8
|
+
def initialize(&block)
|
9
|
+
@banner = "Loading"
|
10
|
+
@type = :spinner
|
11
11
|
@message = "Done"
|
12
|
+
@delay = nil
|
13
|
+
@action = nil
|
14
|
+
@output = :inline
|
12
15
|
|
13
|
-
if
|
14
|
-
|
15
|
-
|
16
|
-
instance_eval &proc
|
16
|
+
if block_given?
|
17
|
+
@outer_scope_object = eval("self", block.binding)
|
18
|
+
instance_eval &block
|
17
19
|
end
|
18
|
-
|
19
|
-
self
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
23
23
|
# Getter and setter for the action block
|
24
24
|
#
|
25
25
|
def action(&block)
|
26
|
-
@action = block
|
26
|
+
@action = block if block
|
27
27
|
|
28
28
|
@action
|
29
29
|
end
|
30
30
|
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
|
37
|
-
|
31
|
+
# @method banner(banner)
|
32
|
+
# @method type(type)
|
33
|
+
# @method message(message)
|
34
|
+
# @method delay(delay)
|
35
|
+
# @method output(output)
|
36
|
+
# Getters and setters for `banner`, `type`, `message`, `delay` and `output`
|
37
|
+
# attributes
|
38
|
+
# @note For getting, use method without arguments
|
39
|
+
# e.g. `banner`<br />
|
40
|
+
# For setting, use method with arguments
|
41
|
+
# e.g. `banner "my banner"`
|
42
|
+
#
|
43
|
+
%w[banner type message delay output].each do |method|
|
44
|
+
define_method(method) do |*args|
|
38
45
|
var = "@#{method}"
|
39
|
-
return instance_variable_get(var)
|
40
|
-
instance_variable_set(var,
|
46
|
+
return instance_variable_get(var) unless args.first
|
47
|
+
instance_variable_set(var, args.first)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -47,7 +54,7 @@ module SpinningCursor
|
|
47
54
|
# Pass any other methods to the calling class
|
48
55
|
#
|
49
56
|
def method_missing(method, *args, &block)
|
50
|
-
@
|
57
|
+
@outer_scope_object.send method, *args, &block
|
51
58
|
end
|
52
59
|
end
|
53
|
-
end
|
60
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class StopWatch
|
2
|
+
|
3
|
+
#
|
4
|
+
# Instantiate class and call {#measure}
|
5
|
+
#
|
6
|
+
def self.measure(&block)
|
7
|
+
sw = self.new
|
8
|
+
sw.measure &block
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Measures the time taken to process the passed block and returns the
|
13
|
+
# measurment (see {timing})
|
14
|
+
#
|
15
|
+
def measure(&block)
|
16
|
+
start
|
17
|
+
yield
|
18
|
+
stop
|
19
|
+
timing
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Starts timer
|
24
|
+
#
|
25
|
+
def start
|
26
|
+
@start_time = Time.now
|
27
|
+
@stop_time = nil
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Stops timer
|
33
|
+
#
|
34
|
+
def stop
|
35
|
+
if @start_time
|
36
|
+
@stop_time = Time.now
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Resets timer
|
43
|
+
#
|
44
|
+
def reset
|
45
|
+
@start_time = @stop_time = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Returns the elapsed time
|
50
|
+
# @note If the timer has not yet stopped, the time elapsed from the start of
|
51
|
+
# the timer till `Time.now` is returned
|
52
|
+
#
|
53
|
+
def elapsed_time
|
54
|
+
time_now = Time.now
|
55
|
+
(@stop_time || time_now ) - (@start_time || time_now)
|
56
|
+
end
|
57
|
+
|
58
|
+
alias old_inspect inspect
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
puts "#{old_inspect} #{{:elapsed_time => elapsed_time}}"
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Returns the measurement in a hash containing
|
66
|
+
# * the start time
|
67
|
+
# * the stop time
|
68
|
+
# * the total elapsed time
|
69
|
+
#
|
70
|
+
def timing
|
71
|
+
{ :start_time => @start_time,
|
72
|
+
:stop_time => @stop_time,
|
73
|
+
:elapsed_time => elapsed_time }
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
data/spinning_cursor.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "spinning_cursor"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Adnan Abdulhussein"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-07-13"
|
13
13
|
s.description = "Spinning Cursor is a flexible DSL that allows you to easily produce a customizable waiting/loading message for your Ruby command line program. Beautifully keep your users informed with what your program is doing when a more complex solution, such as a progress bar, doesn't fit your needs."
|
14
14
|
s.email = "adnan@prydoni.us"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -29,8 +29,10 @@ Gem::Specification.new do |s|
|
|
29
29
|
"TODO",
|
30
30
|
"VERSION",
|
31
31
|
"lib/spinning_cursor.rb",
|
32
|
+
"lib/spinning_cursor/console_helpers.rb",
|
32
33
|
"lib/spinning_cursor/cursor.rb",
|
33
34
|
"lib/spinning_cursor/parser.rb",
|
35
|
+
"lib/spinning_cursor/stop_watch.rb",
|
34
36
|
"spinning_cursor.gemspec",
|
35
37
|
"test/helper.rb",
|
36
38
|
"test/test_cursors.rb",
|
@@ -49,24 +51,24 @@ Gem::Specification.new do |s|
|
|
49
51
|
|
50
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
51
53
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
52
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.
|
53
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.
|
54
|
-
s.add_development_dependency(%q<yard>, ["
|
54
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.3.5"])
|
55
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
56
|
+
s.add_development_dependency(%q<yard>, ["~> 0.8.6.2"])
|
55
57
|
s.add_development_dependency(%q<redcarpet>, [">= 0"])
|
56
58
|
s.add_development_dependency(%q<github-markup>, [">= 0"])
|
57
59
|
else
|
58
60
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
59
|
-
s.add_dependency(%q<bundler>, ["~> 1.
|
60
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
61
|
-
s.add_dependency(%q<yard>, ["
|
61
|
+
s.add_dependency(%q<bundler>, ["~> 1.3.5"])
|
62
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
63
|
+
s.add_dependency(%q<yard>, ["~> 0.8.6.2"])
|
62
64
|
s.add_dependency(%q<redcarpet>, [">= 0"])
|
63
65
|
s.add_dependency(%q<github-markup>, [">= 0"])
|
64
66
|
end
|
65
67
|
else
|
66
68
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
67
|
-
s.add_dependency(%q<bundler>, ["~> 1.
|
68
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
69
|
-
s.add_dependency(%q<yard>, ["
|
69
|
+
s.add_dependency(%q<bundler>, ["~> 1.3.5"])
|
70
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
71
|
+
s.add_dependency(%q<yard>, ["~> 0.8.6.2"])
|
70
72
|
s.add_dependency(%q<redcarpet>, [">= 0"])
|
71
73
|
s.add_dependency(%q<github-markup>, [">= 0"])
|
72
74
|
end
|
data/test/helper.rb
CHANGED
@@ -18,16 +18,31 @@ require 'spinning_cursor'
|
|
18
18
|
# (http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/)
|
19
19
|
|
20
20
|
require 'stringio'
|
21
|
+
|
22
|
+
def kill_other_threads
|
23
|
+
other_threads = Thread.list - [Thread.current]
|
24
|
+
other_threads.each do |th|
|
25
|
+
th.kill
|
26
|
+
th.join
|
27
|
+
end
|
28
|
+
end
|
21
29
|
|
22
30
|
module Kernel
|
23
31
|
def capture_stdout
|
32
|
+
SpinningCursor.capture_console
|
24
33
|
out = StringIO.new
|
25
|
-
$
|
34
|
+
$console = out
|
26
35
|
yield out
|
27
36
|
ensure
|
28
|
-
|
37
|
+
kill_other_threads
|
38
|
+
$console = STDOUT
|
39
|
+
SpinningCursor.release_console
|
29
40
|
end
|
30
41
|
end
|
31
42
|
|
43
|
+
include SpinningCursor
|
44
|
+
|
45
|
+
Thread.abort_on_exception=true
|
46
|
+
|
32
47
|
class Test::Unit::TestCase
|
33
48
|
end
|
data/test/test_cursors.rb
CHANGED
@@ -2,40 +2,80 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestSpinningCursorCursor < Test::Unit::TestCase
|
4
4
|
context "dots" do
|
5
|
-
|
5
|
+
parsed = Parser.new { type :dots; delay 0.2; banner ""}
|
6
|
+
delay = parsed.delay
|
7
|
+
should "change 'frames' with correct delay" do
|
6
8
|
capture_stdout do |out|
|
7
9
|
dots = Thread.new do
|
8
|
-
SpinningCursor::Cursor.new(
|
10
|
+
SpinningCursor::Cursor.new(parsed).spin
|
9
11
|
end
|
10
|
-
|
12
|
+
# slight delay to get things started
|
13
|
+
sleep (delay/4.0)
|
14
|
+
buffer = "#{ESC_R_AND_CLR}" << "."
|
15
|
+
assert_equal buffer, out.string
|
16
|
+
|
17
|
+
sleep delay
|
18
|
+
buffer << "#{ESC_R_AND_CLR}" << ".."
|
19
|
+
assert_equal buffer, out.string
|
20
|
+
|
21
|
+
sleep delay
|
22
|
+
buffer << "#{ESC_R_AND_CLR}" << "..."
|
23
|
+
assert_equal buffer, out.string
|
24
|
+
|
25
|
+
sleep delay
|
26
|
+
buffer << "#{ESC_R_AND_CLR}"
|
27
|
+
assert_equal buffer, out.string
|
28
|
+
# don't need to go through the whole thing, otherwise test will take
|
29
|
+
# too long
|
11
30
|
dots.kill
|
12
|
-
# \r\e[0K is move cursor to the start of the line and clear line
|
13
|
-
# in bash
|
14
|
-
assert_equal "...\r\e[0K", out.string
|
15
31
|
end
|
16
32
|
end
|
17
33
|
end
|
18
34
|
|
19
35
|
context "spinner" do
|
20
36
|
should "cycle through correctly" do
|
37
|
+
parsed = Parser.new { type :spinner; delay 0.2; banner ""}
|
38
|
+
delay = parsed.delay
|
39
|
+
capture_stdout do |out|
|
40
|
+
spinner = Thread.new do
|
41
|
+
SpinningCursor::Cursor.new(parsed).spin
|
42
|
+
end
|
43
|
+
# slight delay to get things started
|
44
|
+
sleep (delay/3.0)
|
45
|
+
buffer = (ESC_R_AND_CLR + "|")
|
46
|
+
assert_equal buffer, out.string
|
47
|
+
buffer += (ESC_R_AND_CLR + "/")
|
48
|
+
sleep delay
|
49
|
+
assert_equal buffer, out.string
|
50
|
+
buffer += (ESC_R_AND_CLR + "-")
|
51
|
+
sleep delay
|
52
|
+
assert_equal buffer, out.string
|
53
|
+
buffer += (ESC_R_AND_CLR + "\\")
|
54
|
+
sleep delay
|
55
|
+
assert_equal buffer, out.string
|
56
|
+
sleep delay
|
57
|
+
buffer += (ESC_R_AND_CLR + "|")
|
58
|
+
assert_equal buffer, out.string
|
59
|
+
spinner.kill
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
should "changes 'frames' with correct delay" do
|
64
|
+
parsed = Parser.new { type :spinner; delay 0.2; banner ""}
|
65
|
+
delay = parsed.delay
|
21
66
|
capture_stdout do |out|
|
22
67
|
spinner = Thread.new do
|
23
|
-
SpinningCursor::Cursor.new(
|
68
|
+
SpinningCursor::Cursor.new(parsed).spin
|
24
69
|
end
|
25
|
-
sleep 0
|
26
|
-
|
27
|
-
buffer
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
sleep 0.5
|
35
|
-
assert_equal "#{buffer}\\", out.string
|
36
|
-
buffer += "\\\r\e[0K"
|
37
|
-
sleep 0.5
|
38
|
-
assert_equal "#{buffer}|", out.string
|
70
|
+
sleep (delay/4.0)
|
71
|
+
buffer = (ESC_R_AND_CLR + "|")
|
72
|
+
assert_equal buffer, out.string
|
73
|
+
buffer += (ESC_R_AND_CLR + "/")
|
74
|
+
sleep delay
|
75
|
+
# next frame after 'delay' second
|
76
|
+
assert_equal buffer, out.string
|
77
|
+
# don't need to go through the whole thing, otherwise test will take
|
78
|
+
# too long
|
39
79
|
spinner.kill
|
40
80
|
end
|
41
81
|
end
|
data/test/test_exceptions.rb
CHANGED
@@ -17,12 +17,6 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
should "a) raise NoTaskError when getting execution time if no task ran" do
|
21
|
-
assert_raise SpinningCursor::NoTaskError do
|
22
|
-
SpinningCursor.get_exec_time
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
20
|
should "raise CursorNotRunning errors when cursor has run and finished" do
|
27
21
|
SpinningCursor.start
|
28
22
|
SpinningCursor.stop
|
data/test/test_parser.rb
CHANGED
@@ -1,34 +1,78 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class TestSpinningCursorParser < Test::Unit::TestCase
|
4
|
-
context "
|
5
|
-
should "
|
6
|
-
|
7
|
-
|
4
|
+
context "A Parser instance" do
|
5
|
+
should "always respond to outer_scope_object method" do
|
6
|
+
assert_respond_to Parser.new, :outer_scope_object
|
7
|
+
end
|
8
|
+
|
9
|
+
context "initialized WITHOUT a block" do
|
10
|
+
should "have outer_scope_object equal nil" do
|
11
|
+
assert_equal nil, Parser.new.outer_scope_object
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "initialized WITH a block" do
|
16
|
+
should "have outer_scope_object point to 'caller'" do
|
17
|
+
parsed = Parser.new {}
|
18
|
+
assert_equal self, parsed.outer_scope_object
|
19
|
+
end
|
20
|
+
|
21
|
+
context "having an 'action' block within this block" do
|
22
|
+
should "have this action block retrievable with Parser#action" do
|
23
|
+
action_block = Proc.new { }
|
24
|
+
parsed = Parser.new do
|
25
|
+
action &action_block
|
26
|
+
end
|
27
|
+
assert_equal action_block, parsed.action
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "and instance evaluating this block at Parser context" do
|
32
|
+
should "NOT have access to instance variables of outer_scope_object from inside the block" do
|
33
|
+
@outer_instance_variable = 1
|
34
|
+
parsed = Parser.new { @outer_instance_variable = 2 }
|
35
|
+
assert_not_equal 2, @outer_instance_variable
|
36
|
+
assert_equal 2, parsed.instance_variable_get(:@outer_instance_variable)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "have direct access to instance variables of the Parser instance itself" do
|
40
|
+
parsed = Parser.new { @banner = "this is Parser instance"}
|
41
|
+
assert_equal parsed.banner, "this is Parser instance"
|
42
|
+
end
|
43
|
+
|
44
|
+
should "have access to methods of outer_scope_object from inside the block (thanks method_missing)" do
|
45
|
+
def outer_method
|
46
|
+
"Outer Method"
|
47
|
+
end
|
48
|
+
parsed = Parser.new { banner outer_method }
|
49
|
+
assert_equal outer_method, parsed.banner
|
50
|
+
end
|
8
51
|
end
|
9
|
-
parser = SpinningCursor::Parser.new Proc.new { banner banner_text }
|
10
|
-
assert_equal banner_text, (parser.banner nil)
|
11
52
|
end
|
12
53
|
end
|
13
54
|
|
14
|
-
context "banner, type, message and action methods" do
|
55
|
+
context "banner, type, message, delay and action methods" do
|
15
56
|
setup do
|
16
|
-
@parser = SpinningCursor::Parser.new
|
57
|
+
@parser = SpinningCursor::Parser.new
|
17
58
|
end
|
18
59
|
|
19
60
|
should "act as getters and setters" do
|
20
61
|
@parser.banner "a new banner"
|
21
|
-
assert_equal "a new banner",
|
62
|
+
assert_equal "a new banner", @parser.banner
|
22
63
|
|
23
64
|
@parser.type :dots
|
24
|
-
assert_equal :dots,
|
65
|
+
assert_equal :dots, @parser.type
|
25
66
|
|
26
67
|
@parser.message "a message"
|
27
|
-
assert_equal "a message",
|
68
|
+
assert_equal "a message", @parser.message
|
69
|
+
|
70
|
+
@parser.delay 5
|
71
|
+
assert_equal 5, @parser.delay
|
28
72
|
|
29
73
|
proc = Proc.new { }
|
30
74
|
@parser.action &proc
|
31
75
|
assert_equal proc, @parser.action
|
32
76
|
end
|
33
77
|
end
|
34
|
-
end
|
78
|
+
end
|
@@ -6,13 +6,22 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
6
6
|
# Hide any output
|
7
7
|
capture_stdout do |out|
|
8
8
|
SpinningCursor.start do
|
9
|
-
action { sleep 1 }
|
9
|
+
action { sleep 0.1 }
|
10
10
|
end
|
11
11
|
# Give it some time to abort
|
12
12
|
assert_equal false, SpinningCursor.alive?
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
should "Parser#outer_scope_object point to 'caller'" do
|
17
|
+
capture_stdout do |out|
|
18
|
+
SpinningCursor.start { }
|
19
|
+
parsed = SpinningCursor.instance_variable_get(:@parsed)
|
20
|
+
assert_equal self, parsed.outer_scope_object
|
21
|
+
SpinningCursor.stop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
16
25
|
should "evalute the block from the calling class" do
|
17
26
|
@num = 1
|
18
27
|
capture_stdout do |out|
|
@@ -23,6 +32,17 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
23
32
|
assert_equal 2, @num
|
24
33
|
end
|
25
34
|
end
|
35
|
+
|
36
|
+
should "raise an exception if something wrong inside the 'action' block" do
|
37
|
+
class SomethingWrongHappened < StandardError; end
|
38
|
+
assert_raise SomethingWrongHappened do
|
39
|
+
capture_stdout do |out|
|
40
|
+
SpinningCursor.start do
|
41
|
+
action { raise SomethingWrongHappened }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
26
46
|
end
|
27
47
|
|
28
48
|
context "when an action block isn't passed it" do
|
@@ -31,7 +51,7 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
31
51
|
SpinningCursor.start do
|
32
52
|
banner "no action block"
|
33
53
|
end
|
34
|
-
sleep
|
54
|
+
sleep 0.5
|
35
55
|
assert_equal true, SpinningCursor.alive?
|
36
56
|
SpinningCursor.stop
|
37
57
|
sleep 0.1
|
@@ -56,12 +76,14 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
56
76
|
|
57
77
|
should "stop and display error if an unmanaged exception is thrown" do
|
58
78
|
capture_stdout do |out|
|
59
|
-
|
60
|
-
|
61
|
-
|
79
|
+
begin
|
80
|
+
SpinningCursor.start do
|
81
|
+
action do
|
82
|
+
raise "An exception!"
|
83
|
+
end
|
62
84
|
end
|
85
|
+
rescue # Just to let the test go on
|
63
86
|
end
|
64
|
-
|
65
87
|
assert_equal true, (out.string.include? "An exception!")
|
66
88
|
end
|
67
89
|
end
|
@@ -85,18 +107,61 @@ class TestSpinningCursor < Test::Unit::TestCase
|
|
85
107
|
should "allow you to change the banner" do
|
86
108
|
capture_stdout do |out|
|
87
109
|
SpinningCursor.start do
|
110
|
+
delay 0.2
|
88
111
|
action do
|
89
112
|
# Have to give it time to print the banners
|
90
113
|
sleep 0.1
|
91
|
-
assert_equal true, (out.string.include? "Loading")
|
114
|
+
assert_equal true, (out.string.include? "Loading"), "It should initialy show default banner"
|
92
115
|
sleep 0.1
|
93
116
|
SpinningCursor.set_banner "Finishing up"
|
94
|
-
sleep 0.
|
95
|
-
assert_equal true, (out.string.include? "Finishing up")
|
117
|
+
sleep 0.2
|
118
|
+
assert_equal true, (out.string.include? "Finishing up"), "It should have changed banner"
|
96
119
|
sleep 0.1
|
97
120
|
end
|
98
121
|
end
|
99
122
|
end
|
100
123
|
end
|
101
124
|
end
|
125
|
+
|
126
|
+
context "when running for the second time" do
|
127
|
+
should "(without a block) return similar timing values" do
|
128
|
+
capture_stdout do |out|
|
129
|
+
SpinningCursor.start
|
130
|
+
sleep 0.2
|
131
|
+
result = SpinningCursor.stop
|
132
|
+
timing_1 = result[:elapsed_time]
|
133
|
+
|
134
|
+
SpinningCursor.start
|
135
|
+
sleep 0.2
|
136
|
+
result = SpinningCursor.stop
|
137
|
+
timing_2 = result[:elapsed_time]
|
138
|
+
|
139
|
+
assert_equal (timing_1*10).round, (timing_2*10).round,
|
140
|
+
"t1 #{timing_1} and t2 #{timing_2} should be equal"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
should "(with a block) return similar timing values" do
|
145
|
+
capture_stdout do |out|
|
146
|
+
result =
|
147
|
+
SpinningCursor.start do
|
148
|
+
action do
|
149
|
+
sleep 0.2
|
150
|
+
end
|
151
|
+
end
|
152
|
+
timing_1 = result[:elapsed_time]
|
153
|
+
|
154
|
+
result =
|
155
|
+
SpinningCursor.start do
|
156
|
+
action do
|
157
|
+
sleep 0.2
|
158
|
+
end
|
159
|
+
end
|
160
|
+
timing_2 = result[:elapsed_time]
|
161
|
+
|
162
|
+
assert_equal (timing_1*10).round, (timing_2*10).round,
|
163
|
+
"t1 #{timing_1} and t2 #{timing_2} should be equal"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
102
167
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spinning_cursor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: shoulda
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 1.
|
37
|
+
version: 1.3.5
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 1.
|
45
|
+
version: 1.3.5
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: jeweler
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.8.
|
53
|
+
version: 1.8.4
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,23 +58,23 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.8.
|
61
|
+
version: 1.8.4
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: yard
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 0.8.6.2
|
70
70
|
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: 0.8.6.2
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: redcarpet
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,8 +130,10 @@ files:
|
|
130
130
|
- TODO
|
131
131
|
- VERSION
|
132
132
|
- lib/spinning_cursor.rb
|
133
|
+
- lib/spinning_cursor/console_helpers.rb
|
133
134
|
- lib/spinning_cursor/cursor.rb
|
134
135
|
- lib/spinning_cursor/parser.rb
|
136
|
+
- lib/spinning_cursor/stop_watch.rb
|
135
137
|
- spinning_cursor.gemspec
|
136
138
|
- test/helper.rb
|
137
139
|
- test/test_cursors.rb
|
@@ -153,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
153
155
|
version: '0'
|
154
156
|
segments:
|
155
157
|
- 0
|
156
|
-
hash:
|
158
|
+
hash: 2712039492645402918
|
157
159
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
160
|
none: false
|
159
161
|
requirements:
|