text-to-noise 0.2.2 → 0.3.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/.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
|