text-to-noise 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +79 -17
- data/bin/text_to_noise +6 -8
- data/features/commandline.feature +0 -3
- data/features/configuration.feature +50 -10
- data/features/support/env.rb +3 -0
- data/lib/text_to_noise/command_line.rb +8 -5
- data/lib/text_to_noise/iteration_mapping_condition.rb +24 -0
- data/lib/text_to_noise/noise_mapping.rb +89 -0
- data/lib/text_to_noise/player.rb +8 -1
- data/lib/text_to_noise/{mapper.rb → router.rb} +7 -11
- data/lib/text_to_noise/version.rb +1 -1
- data/sample.sounds.rb +14 -6
- data/sounds/birds/owl-short.wav +0 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/text_to_noise/command_line_spec.rb +13 -13
- data/spec/text_to_noise/iteration_mapping_condition_spec.rb +30 -0
- data/spec/text_to_noise/noise_mapping_spec.rb +177 -0
- data/spec/text_to_noise/player_spec.rb +32 -0
- data/spec/text_to_noise/{mapper_spec.rb → router_spec.rb} +22 -22
- data/watchr.rb +6 -15
- metadata +14 -8
- data/lib/text_to_noise/mapping.rb +0 -58
- data/spec/text_to_noise/mapping_spec.rb +0 -91
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -19,13 +19,27 @@ Stuff that I had to do to get this running:
|
|
19
19
|
2. Install `text_to_noise` via [Rubygems][rubygems]:
|
20
20
|
`gem install text-to-noise`
|
21
21
|
|
22
|
+
Usage
|
23
|
+
-----
|
24
|
+
|
25
|
+
First, create a sound mapping configuration as shown below. Then you can pipe
|
26
|
+
a log into the `text_to_noise` script and it will start chirping:
|
27
|
+
|
28
|
+
tail -f /var/log/mylog | text_to_noise my.sounds.rb
|
29
|
+
|
30
|
+
Alternatively, you can run `text_to_noise` on an existing file:
|
31
|
+
|
32
|
+
text_to_noise my.sounds.rb -f file.log
|
33
|
+
|
34
|
+
Text-To-Noise will cease processing when it reaches the end of the file.
|
35
|
+
|
22
36
|
|
23
37
|
Configuration
|
24
38
|
=============
|
25
39
|
|
26
40
|
Text-To-Noise is configured with a Ruby file. The configuration contains a set
|
27
41
|
of rules for mapping a line of input text to a sound. Each mapping is a single
|
28
|
-
method of the form `map( pattern ).to "sound"
|
42
|
+
method of the form `map( pattern ).to "sound"`:
|
29
43
|
|
30
44
|
map( /a regex matching log lines to trigger sounds/ ).to "a sound name to play"
|
31
45
|
|
@@ -55,9 +69,23 @@ object returned from the regular expression match:
|
|
55
69
|
match_data[1].to_i > 500
|
56
70
|
}.to "vulture"
|
57
71
|
|
58
|
-
The above rule will play a vulture sound iff a line matches the expression
|
59
|
-
returns true.
|
60
|
-
page takes longer than 500ms to render.
|
72
|
+
The above rule will play a vulture sound **iff** a line matches the expression
|
73
|
+
_and_ the block returns true. Applied to a Rails log, the above rule will play
|
74
|
+
a vulture sound whenever a page takes longer than 500ms to render.
|
75
|
+
|
76
|
+
Additional patterns may be added with the `when` condition:
|
77
|
+
|
78
|
+
map( /Completed in (\d+)ms/ ) { |match_data|
|
79
|
+
match_data[1].to_i > 500
|
80
|
+
}.when { |match_data|
|
81
|
+
match_data[1].to_i < 55
|
82
|
+
}.to "vulture"
|
83
|
+
|
84
|
+
The sound will play if _any_ of the given conditions match.
|
85
|
+
|
86
|
+
Since the configuration file is Ruby, you could conceivable do just about
|
87
|
+
anything you want in the condition block.
|
88
|
+
|
61
89
|
|
62
90
|
For additional details, see the Cucumber [features][Features]. Also, have a
|
63
91
|
look at the [sample][SampleConfig] configuration.
|
@@ -87,6 +115,7 @@ configurations:
|
|
87
115
|
mockingbird
|
88
116
|
nightingale
|
89
117
|
owl
|
118
|
+
owl-short
|
90
119
|
peacock
|
91
120
|
pigeons
|
92
121
|
red_lories
|
@@ -94,23 +123,60 @@ configurations:
|
|
94
123
|
vulture
|
95
124
|
whipperwhill
|
96
125
|
|
97
|
-
Soon you'll be able to add your own `wav` files for playback, but not just yet.
|
98
126
|
|
127
|
+
Adding Your Own Sounds
|
128
|
+
----------------------
|
99
129
|
|
100
|
-
|
101
|
-
|
130
|
+
To make your own sounds available for play, add `sound_path` declarations to
|
131
|
+
your mapping configuration:
|
102
132
|
|
103
|
-
|
104
|
-
|
133
|
+
sound_path "my_sounds/jungle"
|
134
|
+
sound_path "my_sounds/circus"
|
105
135
|
|
106
|
-
|
136
|
+
map /Session/ => "clown"
|
137
|
+
map /404/ => "monkeys"
|
107
138
|
|
108
|
-
|
139
|
+
Each `sound_path` is a directory containing wav files. Now you can specify
|
140
|
+
mappings to wav files in the specified directories. As with the included
|
141
|
+
sounds, the '.wav' extension is optional.
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
Example
|
146
|
+
=======
|
147
|
+
|
148
|
+
Here's a starting point if you're sampling a Rails log:
|
109
149
|
|
110
|
-
|
150
|
+
# rails.configuration.rb
|
151
|
+
sound_path "tmp/sounds" # if you've got some of your own sounds you'd like to try
|
152
|
+
|
153
|
+
map /Rendered/ => %w(cardinal crickets canary), :every => 6
|
154
|
+
map /Processing/ => "crickets", :every => 4
|
155
|
+
|
156
|
+
map /User Load/ => %w(nightingale crickets canary)
|
157
|
+
map /SessionsController#new/ => "owl-short"
|
158
|
+
|
159
|
+
map /404 Not Found/ => "hawk"
|
160
|
+
map /RoutingError/ => "hawk"
|
161
|
+
|
162
|
+
map( /Completed in (\d+)ms/ ) { |match_data|
|
163
|
+
match_data[1].to_i > 500
|
164
|
+
}
|
165
|
+
|
166
|
+
Start it up with:
|
167
|
+
|
168
|
+
tail -f /var/www/myrailsapp/shared/logs/production.log | text_to_noise sample.configuration.rb
|
169
|
+
|
170
|
+
Or perhaps you're interested in SSH activity on your server:
|
171
|
+
|
172
|
+
# ssh.sounds.rb
|
173
|
+
match /sshd.*Accepted/ => %w[rooster hawk chicken crow]
|
111
174
|
|
112
|
-
|
175
|
+
Get this started with:
|
113
176
|
|
177
|
+
echo 'match /sshd.*Accepted/ => %w[rooster hawk chicken crow]' > ssh.sounds.rb
|
178
|
+
tail -f /var/log/secure.log | text_to_noise ssh.sounds.rb
|
179
|
+
|
114
180
|
|
115
181
|
TODO
|
116
182
|
----
|
@@ -118,12 +184,8 @@ TODO
|
|
118
184
|
At the moment, this only supports playing some free bird songs that are included in the gem.
|
119
185
|
Highest priority is the ability to add your own sound sets for playback.
|
120
186
|
|
121
|
-
* Add sounds to the available noises for playback
|
122
187
|
* Capistrano integration
|
123
188
|
* Automatically refresh configurations
|
124
|
-
* Add an 'every' option to throttle sounds for comman events
|
125
|
-
* Add generators to create stub configurations
|
126
|
-
* Support sound themes?
|
127
189
|
|
128
190
|
|
129
191
|
[Homebrew]:http://mxcl.github.com/homebrew
|
data/bin/text_to_noise
CHANGED
@@ -19,8 +19,6 @@ arg_parser = OptionParser.new do |opts|
|
|
19
19
|
|
20
20
|
opts.on( "-f", "--file FILE",
|
21
21
|
"Read input from FILE. Defaults to stdin" ) { |f| options[:input] = File.open( f, "r" ) }
|
22
|
-
opts.on( "-c", "--config MAPPING_CONFIG",
|
23
|
-
"Read input to sound mapping configuration from MAPPING_CONFIG" ) { |c| options[:config] = c }
|
24
22
|
opts.on( "-m", "--mute",
|
25
23
|
"Don't play any sounds, just print what matched" ) { options[:mute] = true }
|
26
24
|
opts.on( "-t", "--throttle DELAY",
|
@@ -32,18 +30,18 @@ arg_parser = OptionParser.new do |opts|
|
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
35
|
-
arg_parser.parse!
|
33
|
+
mapping_files = arg_parser.parse!
|
36
34
|
|
37
35
|
begin
|
38
|
-
TextToNoise::CommandLine.new( options ).run
|
39
|
-
rescue ArgumentError
|
36
|
+
TextToNoise::CommandLine.new( mapping_files, options ).run
|
37
|
+
rescue ArgumentError => e
|
40
38
|
$stderr.puts arg_parser
|
41
39
|
$stderr.puts <<-EOS
|
42
40
|
|
43
41
|
ERROR!
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
Error parsing configuration file, or configuration missing.
|
44
|
+
\t#{e}
|
47
45
|
|
48
46
|
Try this one if you're processing a Rails log:
|
49
47
|
|
@@ -64,7 +62,7 @@ Copy one of those into a file and pass it along to text_to_noise.
|
|
64
62
|
For example:
|
65
63
|
|
66
64
|
echo 'match /sshd.*Accepted/ => %w[rooster hawk chicken crow]' > ssh.sounds.rb
|
67
|
-
tail -f /var/log/secure.log | text_to_noise
|
65
|
+
tail -f /var/log/secure.log | text_to_noise ssh.sounds.rb
|
68
66
|
|
69
67
|
Still having problems?
|
70
68
|
Try logging an issue at https://github.com/tobytripp/text_to_noise/issues
|
@@ -15,7 +15,7 @@ Feature: Mapping input lines to sounds for playback
|
|
15
15
|
|
16
16
|
"""
|
17
17
|
|
18
|
-
When I run `text_to_noise
|
18
|
+
When I run `text_to_noise sound_mapping.rb --file stuff.log --mute`
|
19
19
|
|
20
20
|
Then the output should contain:
|
21
21
|
"""
|
@@ -25,7 +25,8 @@ Feature: Mapping input lines to sounds for playback
|
|
25
25
|
Scenario: Using a Hash to specify mappings
|
26
26
|
Given a file named "sound_mapping.rb" with:
|
27
27
|
"""
|
28
|
-
map /caw/
|
28
|
+
map /caw/ => "crow"
|
29
|
+
map /bakawk/ => "chicken"
|
29
30
|
"""
|
30
31
|
|
31
32
|
And a file named "input.log" with:
|
@@ -34,7 +35,7 @@ Feature: Mapping input lines to sounds for playback
|
|
34
35
|
bakawk!
|
35
36
|
"""
|
36
37
|
|
37
|
-
When I run `text_to_noise
|
38
|
+
When I run `text_to_noise sound_mapping.rb -f input.log -m`
|
38
39
|
|
39
40
|
Then the output should contain "Playing crow.wav"
|
40
41
|
And the output should contain "Playing chicken.wav"
|
@@ -58,7 +59,7 @@ Feature: Mapping input lines to sounds for playback
|
|
58
59
|
User Load (7.1ms)
|
59
60
|
"""
|
60
61
|
|
61
|
-
When I run `text_to_noise
|
62
|
+
When I run `text_to_noise sound_mapping.rb -f input.log -m`
|
62
63
|
|
63
64
|
Then the output should contain "Playing slow_query.wav"
|
64
65
|
And the output should not contain "Playing slow_request.wav"
|
@@ -66,7 +67,8 @@ Feature: Mapping input lines to sounds for playback
|
|
66
67
|
Scenario: Inputs that match multiple rules should fire all sounds
|
67
68
|
Given a file named "sound_mapping.rb" with:
|
68
69
|
"""
|
69
|
-
map /caw/
|
70
|
+
map /caw/ => "crow"
|
71
|
+
map /bakawk/ => "chicken"
|
70
72
|
"""
|
71
73
|
|
72
74
|
And a file named "input.log" with:
|
@@ -74,14 +76,13 @@ Feature: Mapping input lines to sounds for playback
|
|
74
76
|
caw bakawk!
|
75
77
|
"""
|
76
78
|
|
77
|
-
When I run `text_to_noise
|
79
|
+
When I run `text_to_noise sound_mapping.rb -f input.log -m`
|
78
80
|
|
79
81
|
Then the output should contain "Playing crow.wav"
|
80
82
|
And the output should contain "Playing chicken.wav"
|
81
83
|
|
82
|
-
@wip
|
83
84
|
Scenario: Throttling a match
|
84
|
-
Given a file named "sound_mapping" with:
|
85
|
+
Given a file named "sound_mapping.rb" with:
|
85
86
|
"""
|
86
87
|
map /Rendered/ => 'crickets', :every => 5
|
87
88
|
map( /page/ ).to( 'crickets' ).every( 5 )
|
@@ -103,10 +104,49 @@ Feature: Mapping input lines to sounds for playback
|
|
103
104
|
Rendered a page
|
104
105
|
"""
|
105
106
|
|
106
|
-
When I run `text_to_noise
|
107
|
+
When I run `text_to_noise sound_mapping.rb -f input.short.log -m`
|
107
108
|
|
108
109
|
Then the output should not contain "Playing crickets.wav"
|
109
110
|
|
110
|
-
When I run `text_to_noise
|
111
|
+
When I run `text_to_noise sound_mapping.rb -f input.long.log -m`
|
111
112
|
|
112
113
|
Then the output should contain "Playing crickets.wav"
|
114
|
+
|
115
|
+
Scenario: Throttling with a Proc
|
116
|
+
Given a file named "sound_mapping" with:
|
117
|
+
"""
|
118
|
+
map( /Rendered (\w+) page/ ).to( 'frogs' ).when { |md| md[1] == 'A' }
|
119
|
+
map( /Rendered (\w+) page/ ).to( 'crickets' ).when { |md| md[1] == 'B' }
|
120
|
+
"""
|
121
|
+
|
122
|
+
And a file named "input.log" with:
|
123
|
+
"""
|
124
|
+
Rendered A page
|
125
|
+
"""
|
126
|
+
|
127
|
+
When I run `text_to_noise sound_mapping -f input.log -m`
|
128
|
+
|
129
|
+
Then the output should not contain "Playing crickets.wav"
|
130
|
+
But the output should contain "Playing frogs.wav"
|
131
|
+
|
132
|
+
Scenario: Adding sound directories
|
133
|
+
Given a file named "sound_mapping" with:
|
134
|
+
"""
|
135
|
+
sound_path 'other_sounds'
|
136
|
+
map /Rendered/ => 'blurp'
|
137
|
+
"""
|
138
|
+
|
139
|
+
And a directory named "other_sounds"
|
140
|
+
And an empty file named "blurp.wav"
|
141
|
+
|
142
|
+
And a file named "input.log" with:
|
143
|
+
"""
|
144
|
+
Rendered a page
|
145
|
+
"""
|
146
|
+
|
147
|
+
When I run `text_to_noise sound_mapping -f input.log -m`
|
148
|
+
|
149
|
+
Then the output should contain "Playing blurp.wav"
|
150
|
+
|
151
|
+
@wip
|
152
|
+
Scenario: Set volume for a sound
|
data/features/support/env.rb
CHANGED
@@ -7,20 +7,23 @@ module TextToNoise
|
|
7
7
|
|
8
8
|
DEFAULT_FILE_DELAY = 100
|
9
9
|
|
10
|
-
def initialize( options={} )
|
10
|
+
def initialize( mapping_configurations, options={} )
|
11
11
|
@options = {
|
12
12
|
:input => $stdin
|
13
13
|
}.merge options
|
14
14
|
|
15
|
-
|
15
|
+
configs = Array === mapping_configurations ? mapping_configurations : [mapping_configurations]
|
16
|
+
|
17
|
+
raise ArgumentError, "No configuration file provided." if configs.empty?
|
18
|
+
|
19
|
+
@mapping = Router.parse File.read( configs.first )
|
16
20
|
|
17
|
-
@mapping = Mapper.parse File.read( @options[:config] )
|
18
21
|
TextToNoise.player = self.player
|
19
22
|
TextToNoise.throttle_delay = @options[:throttle] if @options[:throttle]
|
20
23
|
TextToNoise.throttle_delay = @options[:throttle] || DEFAULT_FILE_DELAY if @options[:input] != $stdin
|
21
|
-
TextToNoise.logger.level
|
24
|
+
TextToNoise.logger.level = Logger::DEBUG if @options[:debug]
|
22
25
|
rescue Errno::ENOENT => e
|
23
|
-
raise ArgumentError, "Could not locate configuration file: '#{
|
26
|
+
raise ArgumentError, "Could not locate configuration file: '#{configs.first}' (#{e})"
|
24
27
|
end
|
25
28
|
|
26
29
|
def run
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TextToNoise
|
2
|
+
class IterationMappingCondition
|
3
|
+
attr_accessor :count
|
4
|
+
|
5
|
+
def initialize( count )
|
6
|
+
self.count = count
|
7
|
+
@iteration = 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def play?( match_data=nil )
|
11
|
+
@iteration += 1
|
12
|
+
count == 1 || (@iteration % count == 0)
|
13
|
+
end
|
14
|
+
alias_method :call, :play?
|
15
|
+
|
16
|
+
def count=( new_count )
|
17
|
+
if new_count > 0
|
18
|
+
@count = new_count
|
19
|
+
else
|
20
|
+
@count = 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TextToNoise
|
3
|
+
class NoiseMapping
|
4
|
+
include Logging
|
5
|
+
attr_accessor :targets, :matcher_conditions
|
6
|
+
|
7
|
+
def initialize( expression_or_map, &block )
|
8
|
+
debug "Parsing expression: #{expression_or_map.inspect}"
|
9
|
+
|
10
|
+
@matcher_conditions = []
|
11
|
+
@regex = nil
|
12
|
+
|
13
|
+
case expression_or_map
|
14
|
+
when Regexp
|
15
|
+
@regex = expression_or_map
|
16
|
+
when Hash
|
17
|
+
expression_or_map.each do |k,v|
|
18
|
+
case k
|
19
|
+
when Regexp
|
20
|
+
@regex = k
|
21
|
+
self.to v
|
22
|
+
else
|
23
|
+
self.send k.to_sym, v
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
27
|
+
raise ArgumentError, "Unrecognized Mapping configuration: #{expression_or_map.inspect}"
|
28
|
+
end
|
29
|
+
|
30
|
+
raise ArgumentError,
|
31
|
+
"Bad configuration line. Missing match expression in \"#{expression_or_map.inspect}\"" if @regex.nil?
|
32
|
+
|
33
|
+
matcher_conditions << block if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def ===( other )
|
37
|
+
match_data = @regex.match( other )
|
38
|
+
!match_data.nil? && play?( match_data )
|
39
|
+
end
|
40
|
+
|
41
|
+
def to( sound_or_sounds )
|
42
|
+
if sound_or_sounds.is_a? Array
|
43
|
+
sounds = sound_or_sounds
|
44
|
+
else
|
45
|
+
sounds = [sound_or_sounds]
|
46
|
+
end
|
47
|
+
|
48
|
+
sounds.each do |sound|
|
49
|
+
s = sound
|
50
|
+
s += ".wav" unless sound =~ /.wav$/
|
51
|
+
self.targets << Proc.new {
|
52
|
+
info "#{self.class.name} : #{@regex.inspect} -> #{sound}"
|
53
|
+
TextToNoise.player.play s
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def every( iteration_count )
|
61
|
+
@matcher_conditions << IterationMappingCondition.new( iteration_count )
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
def when( &clause )
|
66
|
+
@matcher_conditions << clause
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def call()
|
71
|
+
debug "Calling '#{@regex.inspect}' target…"
|
72
|
+
target.call
|
73
|
+
end
|
74
|
+
|
75
|
+
def targets() @targets ||= []; end
|
76
|
+
def target()
|
77
|
+
@i = -1 unless @i
|
78
|
+
@i = (@i + 1) % targets.size
|
79
|
+
self.targets[@i]
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def play?( match_data )
|
85
|
+
return true if @matcher_conditions.empty?
|
86
|
+
@matcher_conditions.any? { |c| c.call match_data }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/text_to_noise/player.rb
CHANGED
@@ -13,7 +13,7 @@ module TextToNoise
|
|
13
13
|
self.class.load_rubygame
|
14
14
|
|
15
15
|
Rubygame::Sound.autoload_dirs << SOUND_DIR
|
16
|
-
themes = Dir.new(SOUND_DIR).entries.reject { |e| e =~
|
16
|
+
themes = Dir.new(SOUND_DIR).entries.reject { |e| e =~ /^[.]/ }
|
17
17
|
Rubygame::Sound.autoload_dirs.concat themes.map { |t| File.join SOUND_DIR, t }
|
18
18
|
|
19
19
|
@sounds = []
|
@@ -35,6 +35,10 @@ module TextToNoise
|
|
35
35
|
not @sounds.empty?
|
36
36
|
end
|
37
37
|
|
38
|
+
def sound_dirs()
|
39
|
+
Rubygame::Sound.autoload_dirs
|
40
|
+
end
|
41
|
+
|
38
42
|
def available_sounds()
|
39
43
|
Rubygame::Sound.autoload_dirs.map do |dir|
|
40
44
|
Dir[ "#{dir}/*.wav" ].map { |f| File.basename f }
|
@@ -44,6 +48,9 @@ module TextToNoise
|
|
44
48
|
def self.load_rubygame()
|
45
49
|
old_verbose, $VERBOSE = $VERBOSE, nil
|
46
50
|
old_stream, stream = $stdout.dup, $stdout
|
51
|
+
|
52
|
+
return if defined? Rubygame::Sound
|
53
|
+
|
47
54
|
stream.reopen '/dev/null'
|
48
55
|
stream.sync = true
|
49
56
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module TextToNoise
|
2
|
-
class
|
2
|
+
class Router
|
3
3
|
include Logging
|
4
4
|
attr_accessor :mappings
|
5
5
|
|
@@ -22,18 +22,14 @@ module TextToNoise
|
|
22
22
|
matches.map { |m| m.call }
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
def sound_path( path )
|
26
|
+
TextToNoise.player.sound_dirs << path
|
27
|
+
end
|
26
28
|
|
27
29
|
def match( expression, &block )
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
else
|
33
|
-
debug "Creating map for #{expression.inspect}"
|
34
|
-
mappings << mapping = Mapping.new( expression, &block )
|
35
|
-
mapping
|
36
|
-
end
|
30
|
+
debug "Creating map for #{expression.inspect}"
|
31
|
+
mappings << mapping = NoiseMapping.new( expression, &block )
|
32
|
+
mapping
|
37
33
|
end
|
38
34
|
alias_method :map, :match
|
39
35
|
end
|
data/sample.sounds.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
sound_path "tmp/sounds"
|
2
|
+
|
3
|
+
map /Rendered/ => %w(cardinal crickets canary), :every => 6
|
4
|
+
map /Processing/ => "crickets", :every => 4
|
5
|
+
|
6
|
+
map /User Load/ => %w"nightingale crickets canary"
|
7
|
+
map /SessionsController#new/ => "owl-short"
|
8
|
+
|
9
|
+
map /404 Not Found/ => "hawk"
|
10
|
+
map /RoutingError/ => "hawk"
|
11
|
+
|
12
|
+
map( /Completed in (\d+)ms/ ) { |match_data|
|
13
|
+
match_data[1].to_i > 500
|
14
|
+
}
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,8 @@ lib = File.expand_path( '../lib/', __FILE__ )
|
|
4
4
|
$:.unshift lib unless $:.include?( lib )
|
5
5
|
|
6
6
|
require 'text_to_noise'
|
7
|
-
TextToNoise.logger
|
7
|
+
TextToNoise.logger = Logger.new "log/test.log"
|
8
|
+
TextToNoise.logger.level = Logger::DEBUG
|
8
9
|
|
9
10
|
Rspec.configure do |c|
|
10
11
|
c.mock_with :rspec
|
@@ -2,18 +2,18 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module TextToNoise
|
4
4
|
describe TextToNoise::CommandLine do
|
5
|
-
let( :mapping ) { double(
|
5
|
+
let( :mapping ) { double( NoiseMapping ) }
|
6
6
|
let( :reader ) { double( LogReader, :call => nil ) }
|
7
7
|
|
8
8
|
before :each do
|
9
|
-
|
9
|
+
Router.stub!( :parse ).and_return mapping
|
10
10
|
LogReader.stub!( :new ).and_return reader
|
11
11
|
File.stub!( :read ).with( "sound_map.rb" ).and_return "config"
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "#initialize" do
|
15
15
|
it "accepts an options object" do
|
16
|
-
CommandLine.new
|
16
|
+
CommandLine.new "sound_map.rb", {}
|
17
17
|
end
|
18
18
|
|
19
19
|
it "throws an error if no config file is given" do
|
@@ -25,45 +25,45 @@ module TextToNoise
|
|
25
25
|
it "raises an error if the config file cannot be found" do
|
26
26
|
File.stub!( :read ).and_raise Errno::ENOENT
|
27
27
|
lambda {
|
28
|
-
CommandLine.new
|
28
|
+
CommandLine.new "not_found"
|
29
29
|
}.should raise_error( ArgumentError )
|
30
30
|
end
|
31
31
|
|
32
32
|
context "when given a 'config' option" do
|
33
|
-
it "instantiates a
|
33
|
+
it "instantiates a NoiseMapping object with the specified configuration" do
|
34
34
|
File.should_receive( :read ).with( "sound_map.rb" ).and_return "config"
|
35
|
-
|
35
|
+
Router.should_receive( :parse ).with( "config" )
|
36
36
|
|
37
|
-
CommandLine.new
|
37
|
+
CommandLine.new "sound_map.rb"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
context "when given the 'mute' option" do
|
42
42
|
it "sets the global Player to an instance of MutePlayer" do
|
43
43
|
TextToNoise.should_receive( :player= ).with instance_of( MutePlayer )
|
44
|
-
CommandLine.new :mute => true
|
44
|
+
CommandLine.new "sound_map.rb", :mute => true
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
context "when given the 'throttle' option" do
|
49
49
|
it "sets the throttle_delay attribute on TextToNoise" do
|
50
50
|
TextToNoise.should_receive( :throttle_delay= ).with 100
|
51
|
-
CommandLine.new
|
51
|
+
CommandLine.new "sound_map.rb", :throttle => 100
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
context "when given a 'file' option" do
|
56
56
|
it "sets a default throttle_delay" do
|
57
57
|
TextToNoise.should_receive( :throttle_delay= ).with 100
|
58
|
-
CommandLine.new
|
58
|
+
CommandLine.new "sound_map.rb", :input => "sample.log"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
describe "#run" do
|
64
|
-
let( :options ) { Hash[:input, :io
|
64
|
+
let( :options ) { Hash[:input, :io] }
|
65
65
|
|
66
|
-
subject { CommandLine.new( options ) }
|
66
|
+
subject { CommandLine.new( "sound_map.rb", options ) }
|
67
67
|
|
68
68
|
|
69
69
|
it "creates a new LogReader object" do
|
@@ -76,7 +76,7 @@ module TextToNoise
|
|
76
76
|
subject.run
|
77
77
|
end
|
78
78
|
|
79
|
-
it "passes an instance of a
|
79
|
+
it "passes an instance of a NoiseMapping to the LogReader" do
|
80
80
|
LogReader.should_receive( :new ).with( anything, mapping )
|
81
81
|
subject.run
|
82
82
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TextToNoise::IterationMappingCondition do
|
4
|
+
describe "construction" do
|
5
|
+
it "accepts a count" do
|
6
|
+
described_class.new 4
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context "for value 1" do
|
11
|
+
subject { described_class.new 1 }
|
12
|
+
|
13
|
+
it "#play? returns true for all calls" do
|
14
|
+
3.times do
|
15
|
+
subject.play?.should be_true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "for value 2" do
|
21
|
+
subject { described_class.new 2 }
|
22
|
+
|
23
|
+
it "#play? returns true on every other call" do
|
24
|
+
subject.play?.should be_false
|
25
|
+
subject.play?.should be_true
|
26
|
+
subject.play?.should be_false
|
27
|
+
subject.play?.should be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TextToNoise::NoiseMapping do
|
4
|
+
|
5
|
+
before { TextToNoise.player = double( TextToNoise::Player ) }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "can accept a Hash" do
|
9
|
+
mapping = described_class.new /exp/ => "target"
|
10
|
+
mapping.target.should be_a( Proc )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "allows the 'every' option to be specified in the Hash" do
|
14
|
+
mapping = described_class.new /exp/ => "target", :every => 3
|
15
|
+
mapping.matcher_conditions.should_not be_empty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#===" do
|
20
|
+
context "when matching against a regex" do
|
21
|
+
subject { described_class.new /green/ }
|
22
|
+
|
23
|
+
it "returns true when the input matches its regex" do
|
24
|
+
subject.should === "green"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns false when the input does not match its regex" do
|
28
|
+
subject.should_not === "blue"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when matching against a Proc" do
|
33
|
+
subject do
|
34
|
+
described_class.new( /green (\d+)/ ) { |match_data| match_data[1].to_i > 5 }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "matches if the block returns true" do
|
38
|
+
should === "green 6"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "does not match if the block returns false" do
|
42
|
+
should_not === "green 1"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#to" do
|
48
|
+
subject { described_class.new /green/ }
|
49
|
+
|
50
|
+
it "sets the target of the mapping to a Proc" do
|
51
|
+
subject.to( "bar" )
|
52
|
+
subject.target.should be_a( Proc )
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sets the target to call Player#play on #call" do
|
56
|
+
subject.to( "bar.wav" )
|
57
|
+
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
58
|
+
|
59
|
+
subject.target.call
|
60
|
+
end
|
61
|
+
|
62
|
+
it "automatically appends .wav, if it's not present" do
|
63
|
+
subject.to( "bar" )
|
64
|
+
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
65
|
+
|
66
|
+
subject.target.call
|
67
|
+
end
|
68
|
+
|
69
|
+
it "can accept a list of target files" do
|
70
|
+
subject.to ["foo", "bar", "baz"]
|
71
|
+
TextToNoise.player.should_receive( :play ).with "foo.wav"
|
72
|
+
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
73
|
+
TextToNoise.player.should_receive( :play ).with "baz.wav"
|
74
|
+
|
75
|
+
subject.target.call
|
76
|
+
subject.target.call
|
77
|
+
subject.target.call
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns self" do
|
81
|
+
subject.to( "foo" ).should == subject
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#every" do
|
86
|
+
context "when passed the value '3'" do
|
87
|
+
subject { described_class.new( /green/ ).to( "red" ).every( 3 ) }
|
88
|
+
|
89
|
+
it "does not match immediately" do
|
90
|
+
subject.should_not === 'green'
|
91
|
+
end
|
92
|
+
|
93
|
+
it "only matches on the given iteration" do
|
94
|
+
subject.should_not === 'green'
|
95
|
+
subject.should_not === 'green'
|
96
|
+
subject.should === 'green'
|
97
|
+
subject.should_not === 'green'
|
98
|
+
subject.should_not === 'green'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when passed the value 1" do
|
103
|
+
subject { described_class.new( /green/ ).to( "red" ).every( 1 ) }
|
104
|
+
|
105
|
+
it "matches on every iteration" do
|
106
|
+
subject.should === 'green'
|
107
|
+
subject.should === 'green'
|
108
|
+
subject.should === 'green'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when passed the value 0" do
|
113
|
+
subject { described_class.new( /green/ ).to( "red" ).every( 0 ) }
|
114
|
+
|
115
|
+
it "matches on every iteration" do
|
116
|
+
subject.should === 'green'
|
117
|
+
subject.should === 'green'
|
118
|
+
subject.should === 'green'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when passed the value -1" do
|
123
|
+
subject { described_class.new( /green/ ).to( "red" ).every( 0 ) }
|
124
|
+
|
125
|
+
it "matches on every iteration" do
|
126
|
+
subject.should === 'green'
|
127
|
+
subject.should === 'green'
|
128
|
+
subject.should === 'green'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when called multiple times" do
|
133
|
+
subject do
|
134
|
+
described_class.new( /green/ ).to( "red" ).
|
135
|
+
every( 3 ).
|
136
|
+
every( 5 )
|
137
|
+
end
|
138
|
+
|
139
|
+
it "fires when any rule matches" do
|
140
|
+
TextToNoise.player.should_receive( :play ).exactly( 3 ).times
|
141
|
+
8.times { subject.call if subject === "green" }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#when" do
|
147
|
+
let( :player ) { TextToNoise.player }
|
148
|
+
|
149
|
+
context "given a Proc that returns true" do
|
150
|
+
subject { described_class.new( /blue/ ).to( "green" ).when { true } }
|
151
|
+
|
152
|
+
it "will match the given input" do
|
153
|
+
subject.should === "blue"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "given a Proc that returns false" do
|
158
|
+
subject { described_class.new( /blue/ ).to( "green" ).when { false } }
|
159
|
+
|
160
|
+
it "does not match the input" do
|
161
|
+
subject.should_not === "blue"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#call" do
|
167
|
+
subject do
|
168
|
+
described_class.new( /green/ ).tap do |mapping|
|
169
|
+
mapping.targets = [Proc.new { "called" }]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it "calls #call on its target" do
|
174
|
+
subject.call.should == "called"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Rubygame
|
4
|
+
class Sound
|
5
|
+
class << self
|
6
|
+
attr_accessor :autoload_dirs
|
7
|
+
|
8
|
+
def []( sound_name )
|
9
|
+
end
|
10
|
+
|
11
|
+
def autoload_dirs()
|
12
|
+
@autoload_dirs ||= []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe TextToNoise::Player do
|
19
|
+
describe "construction" do
|
20
|
+
it "adds the default folder to the autoload paths" do
|
21
|
+
described_class.new
|
22
|
+
Rubygame::Sound.autoload_dirs.should include( TextToNoise::Player::SOUND_DIR )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#sound_dirs" do
|
27
|
+
it "delegates to the underlying rubygame attribute" do
|
28
|
+
subject.sound_dirs << "bar"
|
29
|
+
Rubygame::Sound.autoload_dirs.should include( "bar" )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
module TextToNoise
|
3
|
-
describe
|
3
|
+
describe Router do
|
4
4
|
it "reloads its configuration if it has changed"
|
5
5
|
|
6
6
|
describe ".parse" do
|
7
|
-
let( :mapping ) { double(
|
7
|
+
let( :mapping ) { double( NoiseMapping, :to => nil ) }
|
8
8
|
|
9
9
|
context "given a nil configuration" do
|
10
10
|
it "raises an ArgumentError" do
|
11
11
|
lambda {
|
12
|
-
|
12
|
+
Router.parse nil
|
13
13
|
}.should raise_error( ArgumentError )
|
14
14
|
end
|
15
15
|
end
|
@@ -17,7 +17,7 @@ module TextToNoise
|
|
17
17
|
context "given a blank configuration" do
|
18
18
|
it "raises an ArgumentError" do
|
19
19
|
lambda {
|
20
|
-
|
20
|
+
Router.parse " \t \n"
|
21
21
|
}.should raise_error( ArgumentError )
|
22
22
|
end
|
23
23
|
end
|
@@ -26,30 +26,30 @@ module TextToNoise
|
|
26
26
|
let( :config ) { "match( /brown/ ).to \"blue\"" }
|
27
27
|
|
28
28
|
it "creates a Mapping object for the given configuration line" do
|
29
|
-
|
30
|
-
|
29
|
+
NoiseMapping.should_receive( :new ).with( /brown/ ).and_return mapping
|
30
|
+
Router.parse config
|
31
31
|
end
|
32
32
|
|
33
33
|
it "configures the mapping" do
|
34
|
-
|
34
|
+
NoiseMapping.stub!( :new ).with( /brown/ ).and_return mapping
|
35
35
|
mapping.should_receive( :to ).with( "blue" )
|
36
36
|
|
37
|
-
|
37
|
+
Router.parse config
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
context "given a multiple line configuration" do
|
42
42
|
let( :config ) { 'match( /brown/ ).to "blue"; map( /green/ ).to "orange"' }
|
43
|
-
before {
|
43
|
+
before { NoiseMapping.stub!( :new ).and_return mapping }
|
44
44
|
|
45
45
|
it "configures the second mapping in addition to the first" do
|
46
46
|
mapping.should_receive( :to ).with "blue"
|
47
47
|
mapping.should_receive( :to ).with "orange"
|
48
|
-
|
48
|
+
Router.parse config
|
49
49
|
end
|
50
50
|
|
51
51
|
it "stores the mappings" do
|
52
|
-
|
52
|
+
Router.parse( config ).should have( 2 ).mappings
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -57,20 +57,20 @@ module TextToNoise
|
|
57
57
|
let( :config ) { "match /brown/ => \"blue\"\n" }
|
58
58
|
|
59
59
|
it "configures the mapping" do
|
60
|
-
|
61
|
-
|
60
|
+
NoiseMapping.should_receive( :new ).with( /brown/ => "blue" ).and_return mapping
|
61
|
+
Router.parse config
|
62
62
|
end
|
63
63
|
end
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
describe "#sound_path" do
|
67
|
+
subject { described_class.new }
|
68
|
+
before { TextToNoise.player = double( TextToNoise::Player ) }
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
Mapper.parse config
|
73
|
-
end
|
70
|
+
it "adds the argument to the player's sound paths" do
|
71
|
+
paths = []
|
72
|
+
TextToNoise.player.should_receive( :sound_dirs ).and_return paths
|
73
|
+
subject.sound_path "foo"
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -79,7 +79,7 @@ module TextToNoise
|
|
79
79
|
let( :green ) { /green/ }
|
80
80
|
let( :blue2 ) { /blu/ }
|
81
81
|
|
82
|
-
subject {
|
82
|
+
subject { Router.new.tap { |m| m.mappings = [blue, green, blue2] } }
|
83
83
|
|
84
84
|
it "iterates over its mappings comparing them to the input with #===" do
|
85
85
|
blue.should_receive( :=== ).with( anything )
|
data/watchr.rb
CHANGED
@@ -6,7 +6,9 @@
|
|
6
6
|
#
|
7
7
|
begin
|
8
8
|
require "g"
|
9
|
+
puts "Growl loaded"
|
9
10
|
rescue LoadError
|
11
|
+
puts "No growl library found"
|
10
12
|
end
|
11
13
|
|
12
14
|
def announce( message )
|
@@ -21,12 +23,7 @@ end
|
|
21
23
|
|
22
24
|
def specs_matching( type, name )
|
23
25
|
puts "looking for specs of #{name}"
|
24
|
-
|
25
|
-
if matching_specs.empty?
|
26
|
-
$stderr.puts "No matching specs found! Did you NOT TEST THIS?!"
|
27
|
-
else
|
28
|
-
spec *matching_specs
|
29
|
-
end
|
26
|
+
spec *Dir["spec/**/*#{name}*_spec.rb"]
|
30
27
|
end
|
31
28
|
|
32
29
|
def run_all_tests
|
@@ -37,16 +34,15 @@ end
|
|
37
34
|
def execute( cmd )
|
38
35
|
puts "> #{cmd}"
|
39
36
|
system cmd
|
37
|
+
system 'date'
|
40
38
|
end
|
41
39
|
|
42
40
|
watch( '^spec/[^/]*/(.*)_spec\.rb' ) { |m| spec m[0] }
|
43
41
|
watch( '^spec/spec_helper\.rb' ) { |m| execute "rake spec" }
|
44
42
|
watch( '^spec/support/.*' ) { |m| execute "rake spec" }
|
45
|
-
watch( '^
|
43
|
+
watch( '^app/([^/]+)/(.*)\.rb' ) { |m| specs_matching m[1], m[2] }
|
44
|
+
watch( '^features/(.*)' ) { |m| execute "cucumber #{m[0]}" }
|
46
45
|
watch( '^features/step_definitions/.*' ) { |m| execute "cucumber features" }
|
47
|
-
watch( '^features/([^/]+\.feature)' ) { |m|
|
48
|
-
execute "cucumber #{m[0]}" unless m[1].include? "step_definitions"
|
49
|
-
}
|
50
46
|
|
51
47
|
Signal.trap 'INT' do
|
52
48
|
if @sent_an_int then
|
@@ -59,8 +55,3 @@ Signal.trap 'INT' do
|
|
59
55
|
run_all_tests
|
60
56
|
end
|
61
57
|
end
|
62
|
-
|
63
|
-
# Ctrl-\
|
64
|
-
Signal.trap 'QUIT' do
|
65
|
-
run_all_tests
|
66
|
-
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: text-to-noise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Toby Tripp
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-05-
|
14
|
+
date: 2011-05-22 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rubygame
|
@@ -83,12 +83,13 @@ files:
|
|
83
83
|
- features/support/env.rb
|
84
84
|
- lib/text_to_noise.rb
|
85
85
|
- lib/text_to_noise/command_line.rb
|
86
|
+
- lib/text_to_noise/iteration_mapping_condition.rb
|
86
87
|
- lib/text_to_noise/log_reader.rb
|
87
88
|
- lib/text_to_noise/logging.rb
|
88
|
-
- lib/text_to_noise/mapper.rb
|
89
|
-
- lib/text_to_noise/mapping.rb
|
90
89
|
- lib/text_to_noise/mute_player.rb
|
90
|
+
- lib/text_to_noise/noise_mapping.rb
|
91
91
|
- lib/text_to_noise/player.rb
|
92
|
+
- lib/text_to_noise/router.rb
|
92
93
|
- lib/text_to_noise/version.rb
|
93
94
|
- sample.sounds.rb
|
94
95
|
- sounds/birds/australian_frogmouth.wav
|
@@ -108,6 +109,7 @@ files:
|
|
108
109
|
- sounds/birds/mexican_red_parrot.wav
|
109
110
|
- sounds/birds/mockingbird.wav
|
110
111
|
- sounds/birds/nightingale.wav
|
112
|
+
- sounds/birds/owl-short.wav
|
111
113
|
- sounds/birds/owl.wav
|
112
114
|
- sounds/birds/peacock.wav
|
113
115
|
- sounds/birds/pigeons.wav
|
@@ -119,9 +121,11 @@ files:
|
|
119
121
|
- spec/spec.opts
|
120
122
|
- spec/spec_helper.rb
|
121
123
|
- spec/text_to_noise/command_line_spec.rb
|
124
|
+
- spec/text_to_noise/iteration_mapping_condition_spec.rb
|
122
125
|
- spec/text_to_noise/log_reader_spec.rb
|
123
|
-
- spec/text_to_noise/
|
124
|
-
- spec/text_to_noise/
|
126
|
+
- spec/text_to_noise/noise_mapping_spec.rb
|
127
|
+
- spec/text_to_noise/player_spec.rb
|
128
|
+
- spec/text_to_noise/router_spec.rb
|
125
129
|
- spec/text_to_noise/sound_map.rb
|
126
130
|
- ssh.sounds.rb
|
127
131
|
- text_to_noise.gemspec
|
@@ -162,7 +166,9 @@ test_files:
|
|
162
166
|
- spec/spec.opts
|
163
167
|
- spec/spec_helper.rb
|
164
168
|
- spec/text_to_noise/command_line_spec.rb
|
169
|
+
- spec/text_to_noise/iteration_mapping_condition_spec.rb
|
165
170
|
- spec/text_to_noise/log_reader_spec.rb
|
166
|
-
- spec/text_to_noise/
|
167
|
-
- spec/text_to_noise/
|
171
|
+
- spec/text_to_noise/noise_mapping_spec.rb
|
172
|
+
- spec/text_to_noise/player_spec.rb
|
173
|
+
- spec/text_to_noise/router_spec.rb
|
168
174
|
- spec/text_to_noise/sound_map.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module TextToNoise
|
2
|
-
class Mapping
|
3
|
-
include Logging
|
4
|
-
attr_accessor :targets, :matcher_proc
|
5
|
-
|
6
|
-
def initialize( expression_or_map, &block )
|
7
|
-
case expression_or_map
|
8
|
-
when Regexp
|
9
|
-
@regex = expression_or_map
|
10
|
-
when Hash
|
11
|
-
@regex, target = expression_or_map.to_a.flatten
|
12
|
-
self.to target
|
13
|
-
else
|
14
|
-
raise ArgumentError, "Unrecognized Mapping configuration: #{expression_or_map.inspect}"
|
15
|
-
end
|
16
|
-
|
17
|
-
@matcher_proc = block if block_given?
|
18
|
-
end
|
19
|
-
|
20
|
-
def ===( other )
|
21
|
-
match_data = @regex.match( other )
|
22
|
-
if matcher_proc
|
23
|
-
match_data && matcher_proc.call( match_data )
|
24
|
-
else
|
25
|
-
not match_data.nil?
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def to( sound_or_sounds )
|
30
|
-
if sound_or_sounds.is_a? Array
|
31
|
-
sounds = sound_or_sounds
|
32
|
-
else
|
33
|
-
sounds = [sound_or_sounds]
|
34
|
-
end
|
35
|
-
|
36
|
-
sounds.each do |sound|
|
37
|
-
s = sound
|
38
|
-
s += ".wav" unless sound =~ /.wav$/
|
39
|
-
self.targets << Proc.new {
|
40
|
-
info "#{@regex.inspect} -> #{sound}"
|
41
|
-
TextToNoise.player.play s
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def call()
|
47
|
-
debug "Calling '#{@regex.inspect}' target..."
|
48
|
-
target.call
|
49
|
-
end
|
50
|
-
|
51
|
-
def targets() @targets ||= []; end
|
52
|
-
def target()
|
53
|
-
@i = -1 unless @i
|
54
|
-
@i = (@i + 1) % targets.size
|
55
|
-
self.targets[@i]
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe TextToNoise::Mapping do
|
4
|
-
describe "#initialize" do
|
5
|
-
it "can accept a Hash" do
|
6
|
-
mapping = described_class.new /exp/ => "target"
|
7
|
-
mapping.target.should be_a( Proc )
|
8
|
-
end
|
9
|
-
|
10
|
-
it "stores a passed block for use in later matching" do
|
11
|
-
mapping = described_class.new( /exp/ => "target" ) { |md| true }
|
12
|
-
mapping.matcher_proc.should be_a( Proc )
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "#===" do
|
17
|
-
context "when matching against a regex" do
|
18
|
-
subject { described_class.new /green/ }
|
19
|
-
|
20
|
-
it "returns true when the input matches its regex" do
|
21
|
-
subject.should === "green"
|
22
|
-
end
|
23
|
-
|
24
|
-
it "returns false when the input does not match its regex" do
|
25
|
-
subject.should_not === "blue"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context "when matching against a Proc" do
|
30
|
-
subject do
|
31
|
-
described_class.new( /green (\d+)/ ) { |match_data| match_data[1].to_i > 5 }
|
32
|
-
end
|
33
|
-
|
34
|
-
it "matches if the block returns true" do
|
35
|
-
should === "green 6"
|
36
|
-
end
|
37
|
-
|
38
|
-
it "does not match if the block returns false" do
|
39
|
-
should_not === "green 1"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "#to" do
|
45
|
-
subject { described_class.new /green/ }
|
46
|
-
|
47
|
-
before { TextToNoise.player = double( TextToNoise::Player ) }
|
48
|
-
|
49
|
-
it "sets the target of the mapping to a Proc" do
|
50
|
-
subject.to( "bar" )
|
51
|
-
subject.target.should be_a( Proc )
|
52
|
-
end
|
53
|
-
|
54
|
-
it "sets the target to call Player#play on #call" do
|
55
|
-
subject.to( "bar.wav" )
|
56
|
-
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
57
|
-
|
58
|
-
subject.target.call
|
59
|
-
end
|
60
|
-
|
61
|
-
it "automatically appends .wav, if it's not present" do
|
62
|
-
subject.to( "bar" )
|
63
|
-
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
64
|
-
|
65
|
-
subject.target.call
|
66
|
-
end
|
67
|
-
|
68
|
-
it "can accept a list of target files" do
|
69
|
-
subject.to ["foo", "bar", "baz"]
|
70
|
-
TextToNoise.player.should_receive( :play ).with "foo.wav"
|
71
|
-
TextToNoise.player.should_receive( :play ).with "bar.wav"
|
72
|
-
TextToNoise.player.should_receive( :play ).with "baz.wav"
|
73
|
-
|
74
|
-
subject.target.call
|
75
|
-
subject.target.call
|
76
|
-
subject.target.call
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe "#call" do
|
81
|
-
subject do
|
82
|
-
described_class.new( /green/ ).tap do |mapping|
|
83
|
-
mapping.targets = [Proc.new { "called" }]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
it "calls #call on its target" do
|
88
|
-
subject.call.should == "called"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|