derring-do 1.0.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.
@@ -0,0 +1,52 @@
1
+ Derring-Do
2
+ ==========
3
+
4
+ Derring-Do is a silly progress monitor that you can add to your console
5
+ Ruby applications.
6
+
7
+ It will emit "encouraging" words periodically, to indicate progress is being
8
+ made on a job. If the campaign (or job) is given a target, the progress
9
+ will also include updates saying specifically how far the campaign has gone
10
+ toward that target.
11
+
12
+ Usage
13
+ -----
14
+
15
+ require 'derring-do'
16
+
17
+ # untargetted campaigns (with no specifical goal in mind)
18
+
19
+ derring do |campaign|
20
+ 1000.times do
21
+ campaign.tally_ho!
22
+ sleep 0.2
23
+ end
24
+ end
25
+
26
+ # targetted campaigns (aiming for a particular goal)
27
+
28
+ derring do |campaign|
29
+ campaign.target = 2000
30
+ 1000.times do
31
+ campaign.tally_ho! 2
32
+ sleep 0.2
33
+ end
34
+ end
35
+
36
+ Installation
37
+ ------------
38
+
39
+ gem install derring-do
40
+
41
+ Caveats
42
+ -------
43
+
44
+ I wrote this mostly to teach myself how to use rspec. The idea occurred to me
45
+ while mostly asleep, so while it may not be actually useful, it is certainly
46
+ whimsical.
47
+
48
+ License
49
+ -------
50
+
51
+ This library is placed in the public domain by the author, Jamis Buck. Do
52
+ with it what you will. Please prefer good over evil.
@@ -0,0 +1,26 @@
1
+ require 'rake'
2
+ require 'rake/gempackagetask'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.platform = Gem::Platform::RUBY
11
+ s.summary = "The over-eager progress monitor."
12
+ s.name = 'derring-do'
13
+ s.version = "1.0.0"
14
+ s.add_development_dependency "rspec", "~> 2.1.0"
15
+ s.files = FileList["README.markdown", "Rakefile", "lib/**/*.rb", "spec/**/*.rb", "examples/**/*.rb"].to_a
16
+ s.description = "Derring-Do is a very eager progress monitor for console Ruby applications."
17
+ s.author = "Jamis Buck"
18
+ s.email = "jamis@jamisbuck.org"
19
+ s.homepage = "http://github.com/jamis/derring-do"
20
+ end
21
+
22
+ Rake::GemPackageTask.new(spec) do |pkg|
23
+ pkg.need_zip = true
24
+ pkg.need_tar = true
25
+ end
26
+
@@ -0,0 +1,8 @@
1
+ require 'derring-do'
2
+
3
+ derring do |campaign|
4
+ 1000.times do
5
+ campaign.tally_ho!
6
+ sleep 0.02
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'derring-do'
2
+
3
+ derring do |campaign|
4
+ campaign.target = 2000
5
+ 1000.times do
6
+ campaign.tally_ho! 2
7
+ sleep 0.02
8
+ end
9
+ end
@@ -0,0 +1,111 @@
1
+ module DerringDo
2
+ @@configuration = {
3
+ :update_wait_time => 5, # seconds
4
+ :minor_wait_time => 1, # seconds
5
+ :output_to => STDOUT, # where output is written
6
+ }
7
+
8
+ def self.configuration
9
+ @@configuration
10
+ end
11
+
12
+ class Campaign
13
+ attr_reader :progress
14
+ attr_accessor :target
15
+
16
+ def initialize
17
+ @progress = 0
18
+ @target = nil
19
+ @last_update_at = Time.now - DerringDo.configuration[:update_wait_time]
20
+ @last_minor_update_at = Time.now - DerringDo.configuration[:minor_wait_time]
21
+ end
22
+
23
+ def tally_ho!(n=1)
24
+ @progress += n
25
+ inform_if_ready
26
+ end
27
+
28
+ PANIC_WORDS = [
29
+ "Retreat!",
30
+ "Thomas Jefferson...still survives...",
31
+ "Nothing...but death.",
32
+ "Et tu, Brute?",
33
+ "I have tried so hard to do the right!",
34
+ "They couldn't hit an elephant at this dist--",
35
+ ]
36
+
37
+ def failed_with(error) #:nodoc:
38
+ panic = PANIC_WORDS[rand(PANIC_WORDS.length)]
39
+ DerringDo.configuration[:output_to].puts(panic)
40
+ end
41
+
42
+ INSULTS_ADJECTIVES = %w(yellow-bellied two-faced two-timing no-good spineless)
43
+ INSULTS_NOUNS = ["coward", "Benedict Arnold", "traitor", "wimp"]
44
+
45
+ def aborted! #:nodoc:
46
+ adj = INSULTS_ADJECTIVES.sort_by { rand }[0,3].join(", ")
47
+ noun = INSULTS_NOUNS[rand(INSULTS_NOUNS.length)]
48
+ DerringDo.configuration[:output_to].puts(adj + " " + noun + "!")
49
+ end
50
+
51
+ private
52
+
53
+ ENCOURAGING_WORDS = [
54
+ "Charge!",
55
+ "Into the breach!",
56
+ "Faugh a ballaugh!",
57
+ "Vive la Ruby!",
58
+ "Senta a pua!",
59
+ ]
60
+
61
+ CONGRATULATIONS = [
62
+ "Bob's yer uncle!",
63
+ "GADZOOKS!",
64
+ "Oh, I say! Well done!",
65
+ "Jolly good show!",
66
+ "By Jove! I think you've done it!",
67
+ ]
68
+
69
+ def inform_if_ready
70
+ now = Time.now
71
+
72
+ if target && progress >= target
73
+ word = CONGRATULATIONS[rand(CONGRATULATIONS.length)]
74
+ DerringDo.configuration[:output_to].puts(word)
75
+ elsif now - @last_update_at >= DerringDo.configuration[:update_wait_time]
76
+ @last_minor_update_at = @last_update_at = now
77
+ word = ENCOURAGING_WORDS[rand(ENCOURAGING_WORDS.length)]
78
+ DerringDo.configuration[:output_to].puts(word)
79
+ elsif target && now - @last_minor_update_at >= DerringDo.configuration[:minor_wait_time]
80
+ @last_minor_update_at = now
81
+ DerringDo.configuration[:output_to].puts "#{progress} / #{target}"
82
+ end
83
+ end
84
+ end
85
+
86
+ module Implementation
87
+ def derring
88
+ raise ArgumentError, "`derring' requires a block" unless block_given?
89
+
90
+ campaign = Campaign.new
91
+
92
+ begin
93
+ yield campaign
94
+ rescue Interrupt
95
+ campaign.aborted!
96
+ raise
97
+ rescue Exception => error
98
+ campaign.failed_with(error)
99
+ raise
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ class Object
106
+ if instance_methods.any? { |i| i.to_sym == :derring }
107
+ warn "Object#derring is already present; the `derring-do' gem may behave oddly."
108
+ end
109
+
110
+ include DerringDo::Implementation
111
+ end
@@ -0,0 +1,142 @@
1
+ require 'derring-do'
2
+ require 'stringio'
3
+
4
+ class Interrupted < RuntimeError; end
5
+ trap("INT") { raise Interrupted }
6
+
7
+ describe "derring" do
8
+ before(:each) do
9
+ @io = StringIO.new
10
+ DerringDo.configuration[:output_to] = @io
11
+ DerringDo.configuration[:update_wait_time] = 5
12
+ DerringDo.configuration[:minor_wait_time] = 1
13
+ end
14
+
15
+ context "without a block" do
16
+ it "raises an exception" do
17
+ expect{derring}.to raise_error(ArgumentError)
18
+ end
19
+ end
20
+
21
+ context "with no target" do
22
+ it "provides a campaign to the block" do
23
+ called = false
24
+
25
+ derring do |campaign|
26
+ called = true
27
+ campaign.should_not == nil
28
+ end
29
+
30
+ called.should == true
31
+ end
32
+
33
+ it "increments progress when tally_ho! is called on the campaign" do
34
+ derring do |campaign|
35
+ expect{campaign.tally_ho!}.to change{campaign.progress}.from(0).to(1)
36
+ end
37
+ end
38
+
39
+ it "shouts encouragement initially" do
40
+ derring do |campaign|
41
+ expect{campaign.tally_ho!}.to change{@io.string.length}
42
+ end
43
+ end
44
+
45
+ it "shouts encouragement when time has elapsed" do
46
+ DerringDo.configuration[:update_wait_time] = 0.5
47
+
48
+ derring do |campaign|
49
+ campaign.tally_ho!
50
+ expect{campaign.tally_ho!}.to_not change{@io.string.length}
51
+ sleep 0.5
52
+ expect{campaign.tally_ho!}.to change{@io.string.length}
53
+ end
54
+ end
55
+ end
56
+
57
+ context "with a target" do
58
+ it "provides a campaign to the block" do
59
+ called = false
60
+
61
+ derring do |campaign|
62
+ called = true
63
+ campaign.should_not == nil
64
+ campaign.target = 100
65
+ campaign.target.should == 100
66
+ end
67
+
68
+ called.should == true
69
+ end
70
+
71
+ it "increments progress when tally_ho! is called on the campaign" do
72
+ derring do |campaign|
73
+ campaign.target = 100
74
+ expect{campaign.tally_ho!}.to change{campaign.progress}.from(0).to(1)
75
+ end
76
+ end
77
+
78
+ it "moves toward completion when tally_ho!(n) is called on the campaign" do
79
+ derring do |campaign|
80
+ campaign.target = 100
81
+ expect{campaign.tally_ho! 5}.to change{campaign.progress}.from(0).to(5)
82
+ end
83
+ end
84
+
85
+ it "displays progress when some time has elapsed" do
86
+ DerringDo.configuration[:minor_wait_time] = 0.1
87
+
88
+ derring do |campaign|
89
+ campaign.target = 100
90
+ expect{campaign.tally_ho! 5}.to change{@io.string.length}
91
+ expect{campaign.tally_ho! 5}.to_not change{@io.string.length}
92
+ sleep 0.1
93
+ expect{campaign.tally_ho! 5}.to change{@io.string.length}
94
+ end
95
+ end
96
+
97
+ it "only shouts encouragement when more time has elapsed" do
98
+ DerringDo.configuration[:minor_wait_time] = 5
99
+ DerringDo.configuration[:update_wait_time] = 0.1
100
+
101
+ derring do |campaign|
102
+ campaign.target = 100
103
+ expect{campaign.tally_ho! 5}.to change{@io.string.length}
104
+ expect{campaign.tally_ho! 5}.to_not change{@io.string.length}
105
+ sleep 0.1
106
+ expect{campaign.tally_ho! 5}.to change{@io.string.length}
107
+ end
108
+ end
109
+
110
+ it "shouts congratulations when the target is achieved" do
111
+ derring do |campaign|
112
+ campaign.target = 100
113
+ expect{campaign.tally_ho! 5}.to change{@io.string.length}
114
+ expect{campaign.tally_ho! 95}.to change{@io.string.length}
115
+ end
116
+ end
117
+ end
118
+
119
+ context "when an error occurs" do
120
+ it "shouts a panicked exclamation" do
121
+ expect do
122
+ expect do
123
+ derring do |campaign|
124
+ raise "ouch!"
125
+ end
126
+ end.to raise_error(RuntimeError)
127
+ end.to change{@io.string.length}
128
+ end
129
+ end
130
+
131
+ context "when aborted" do
132
+ it "shouts insults" do
133
+ expect do
134
+ expect do
135
+ derring do |campaign|
136
+ Process.kill("INT", $$)
137
+ end
138
+ end.to raise_error(Interrupted)
139
+ end.to change{@io.string.length}
140
+ end
141
+ end
142
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: derring-do
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jamis Buck
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-13 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 11
30
+ segments:
31
+ - 2
32
+ - 1
33
+ - 0
34
+ version: 2.1.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: Derring-Do is a very eager progress monitor for console Ruby applications.
38
+ email: jamis@jamisbuck.org
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - README.markdown
47
+ - Rakefile
48
+ - lib/derring-do.rb
49
+ - spec/derring_spec.rb
50
+ - examples/simple.rb
51
+ - examples/targetted.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/jamis/derring-do
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.7
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: The over-eager progress monitor.
86
+ test_files: []
87
+