emory 0.1.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 +26 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +193 -0
- data/Rakefile +16 -0
- data/bin/emory +32 -0
- data/emory.gemspec +26 -0
- data/examples/simple-stdout/.emory +15 -0
- data/examples/simple-stdout/.gitignore +1 -0
- data/examples/simple-stdout/src/.gitkeep +0 -0
- data/lib/emory/configuration_file.rb +29 -0
- data/lib/emory/dsl/dsl.rb +54 -0
- data/lib/emory/dsl/handler_builder.rb +78 -0
- data/lib/emory/dsl/teleport_config_builder.rb +62 -0
- data/lib/emory/handlers/abstract_handler.rb +35 -0
- data/lib/emory/handlers/stdout_handler.rb +33 -0
- data/lib/emory/runner.rb +75 -0
- data/lib/emory/teleport_config.rb +7 -0
- data/lib/emory/version.rb +3 -0
- data/lib/emory.rb +1 -0
- data/spec/emory/configuration_file_spec.rb +43 -0
- data/spec/emory/dsl/dsl_spec.rb +91 -0
- data/spec/emory/dsl/handler_builder_spec.rb +163 -0
- data/spec/emory/dsl/teleport_config_builder_spec.rb +116 -0
- data/spec/emory/handlers/abstract_handler_spec.rb +35 -0
- data/spec/emory/handlers/stdout_handler_spec.rb +29 -0
- data/spec/emory/runner_spec.rb +75 -0
- data/spec/spec_helper.rb +10 -0
- data/test/emory/test_configuration_file.rb +10 -0
- metadata +171 -0
data/lib/emory/runner.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'listen'
|
2
|
+
require 'pathname'
|
3
|
+
require 'emory/configuration_file'
|
4
|
+
require 'emory/dsl/dsl'
|
5
|
+
|
6
|
+
module Emory
|
7
|
+
|
8
|
+
class Runner
|
9
|
+
|
10
|
+
LOGGER = Logging.logger[self]
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def start
|
14
|
+
begin
|
15
|
+
LOGGER.debug('Looking for the configuration file')
|
16
|
+
emory_config_file = ConfigurationFile.locate
|
17
|
+
|
18
|
+
LOGGER.debug('Reading configuration file contents')
|
19
|
+
emory_config_contents = File.read(emory_config_file)
|
20
|
+
|
21
|
+
LOGGER.debug("Evaluating configuration file contents:\n====\n#{emory_config_contents}===")
|
22
|
+
config = DSL::Dsl.instance_eval_emoryfile(emory_config_contents, emory_config_file)
|
23
|
+
|
24
|
+
LOGGER.debug('Configuring listeners')
|
25
|
+
configure_listeners(config, File.dirname(emory_config_file))
|
26
|
+
|
27
|
+
Thread.current.join
|
28
|
+
rescue Interrupt
|
29
|
+
LOGGER.info('Shutting down Emory')
|
30
|
+
rescue EmoryConfigurationFileNotFoundException => fileNotFoundException
|
31
|
+
LOGGER.error("#{fileNotFoundException.message}. Please refer to http://tacitknowledge.com/emory for information on how to use Emory.")
|
32
|
+
rescue Exception => e
|
33
|
+
LOGGER.error(e)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def configure_listeners(config, config_location)
|
40
|
+
LOGGER.debug("Config\'s directory is: #{config_location}")
|
41
|
+
config.teleports.each do |teleport|
|
42
|
+
watched_path = normalize_watched_path(config_location, teleport.watched_path)
|
43
|
+
LOGGER.info("Watching directory: #{watched_path}")
|
44
|
+
|
45
|
+
listener = Listen.to(watched_path)
|
46
|
+
listener.ignore(teleport.ignore) unless teleport.ignore.nil?
|
47
|
+
listener.filter(teleport.filter) unless teleport.filter.nil?
|
48
|
+
listener.change(&get_handler_callback(teleport.handler))
|
49
|
+
listener.start(false)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_handler_callback(handler)
|
54
|
+
Proc.new do |modified, added, removed|
|
55
|
+
trigger_handler_method(modified, handler, :modified)
|
56
|
+
trigger_handler_method(added, handler, :added)
|
57
|
+
trigger_handler_method(removed, handler, :removed)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def trigger_handler_method(paths, handler, operation)
|
62
|
+
unless paths.empty?
|
63
|
+
paths.each { |path| handler.send(operation, path) } if handler.respond_to?(operation)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def normalize_watched_path(config_location, watched_path)
|
68
|
+
return watched_path if Pathname.new(watched_path).absolute?
|
69
|
+
File.expand_path(watched_path, config_location)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/lib/emory.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "emory/version"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/configuration_file'
|
3
|
+
|
4
|
+
module Emory
|
5
|
+
|
6
|
+
describe ConfigurationFile do
|
7
|
+
|
8
|
+
context "class object" do
|
9
|
+
|
10
|
+
it "finds config file on its path" do
|
11
|
+
Dir.should_receive(:pwd).and_return('/qwe/asd/zxc/')
|
12
|
+
File.should_receive(:exists?).with('/qwe/asd/zxc/.emory').and_return(false)
|
13
|
+
File.should_receive(:exists?).with('/qwe/asd/.emory').and_return(false)
|
14
|
+
File.should_receive(:exists?).with('/qwe/.emory').and_return(true)
|
15
|
+
|
16
|
+
ConfigurationFile.locate.should == '/qwe/.emory'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds config file in current directory" do
|
20
|
+
Dir.should_receive(:pwd).and_return('/qwe/asd/zxc/')
|
21
|
+
File.should_receive(:exists?).with('/qwe/asd/zxc/.emory').and_return(true)
|
22
|
+
|
23
|
+
ConfigurationFile.locate.should == '/qwe/asd/zxc/.emory'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises exception if config file was not found on its path up to root" do
|
27
|
+
Dir.should_receive(:pwd).and_return('/qwe/asd/zxc/')
|
28
|
+
File.should_receive(:exists?).with('/qwe/asd/zxc/.emory').and_return(false)
|
29
|
+
File.should_receive(:exists?).with('/qwe/asd/.emory').and_return(false)
|
30
|
+
File.should_receive(:exists?).with('/qwe/.emory').and_return(false)
|
31
|
+
File.should_receive(:exists?).with('/.emory').and_return(false)
|
32
|
+
|
33
|
+
proc {
|
34
|
+
ConfigurationFile.locate
|
35
|
+
}.should raise_error(EmoryConfigurationFileNotFoundException,
|
36
|
+
/Configuration file \(\.emory\) was not found/)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/dsl/dsl'
|
3
|
+
require 'emory/dsl/handler_builder'
|
4
|
+
require 'emory/dsl/teleport_config_builder'
|
5
|
+
require 'emory/handlers/abstract_handler'
|
6
|
+
|
7
|
+
module Emory
|
8
|
+
module DSL
|
9
|
+
|
10
|
+
describe Dsl do
|
11
|
+
let(:dsl) { Dsl.new }
|
12
|
+
|
13
|
+
context "class object" do
|
14
|
+
it "parses the supplied teleport config and configures correct object types in frozen collections" do
|
15
|
+
contents = <<-EOM
|
16
|
+
require 'emory/handlers/abstract_handler'
|
17
|
+
|
18
|
+
handler do
|
19
|
+
name :something
|
20
|
+
implementation Emory::Handlers::AbstractHandler
|
21
|
+
events :all
|
22
|
+
end
|
23
|
+
|
24
|
+
teleport do
|
25
|
+
path '/path/to/dir'
|
26
|
+
handler :something
|
27
|
+
end
|
28
|
+
EOM
|
29
|
+
|
30
|
+
config = Dsl.instance_eval_emoryfile(contents, '/path/to/file')
|
31
|
+
config.should have(1).handlers
|
32
|
+
config.handlers.should be_frozen
|
33
|
+
config.handlers[:something].class.should == Emory::Handlers::AbstractHandler
|
34
|
+
config.should have(1).teleports
|
35
|
+
config.teleports.should be_frozen
|
36
|
+
config.teleports[0].class.should == Emory::TeleportConfig
|
37
|
+
end
|
38
|
+
|
39
|
+
it "detects and reports incorrect usage of DSL" do
|
40
|
+
contents = <<-EOM
|
41
|
+
blah_blah_blah
|
42
|
+
EOM
|
43
|
+
|
44
|
+
proc {
|
45
|
+
Dsl.instance_eval_emoryfile(contents, '/path/to/file')
|
46
|
+
}.should raise_error(EmoryMisconfigurationException,
|
47
|
+
/Incorrect contents of .emory file/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "'handler' method" do
|
52
|
+
it "does not allow to add multiple handlers with the same name" do
|
53
|
+
dsl.handlers[:something] = Object.new
|
54
|
+
builder = double('handler_builder')
|
55
|
+
handler = double('handler')
|
56
|
+
HandlerBuilder.should_receive(:new).and_return(builder)
|
57
|
+
builder.should_receive(:build).and_return(handler)
|
58
|
+
handler.should_receive(:name).twice.and_return(:something)
|
59
|
+
|
60
|
+
proc {
|
61
|
+
dsl.handler {}
|
62
|
+
}.should raise_error(DuplicateHandlerNameException)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "adds a handler to its list" do
|
66
|
+
builder = double('handler_builder')
|
67
|
+
handler = double('handler')
|
68
|
+
HandlerBuilder.should_receive(:new).and_return(builder)
|
69
|
+
builder.should_receive(:build).and_return(handler)
|
70
|
+
handler.should_receive(:name).exactly(3).times.and_return(:something)
|
71
|
+
|
72
|
+
dsl.handler {}
|
73
|
+
dsl.should have(1).handlers
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "'teleport' method" do
|
78
|
+
it "adds a teleport to its list" do
|
79
|
+
builder = double('teleport_builder')
|
80
|
+
teleport = double('teleport')
|
81
|
+
TeleportConfigBuilder.should_receive(:new).and_return(builder)
|
82
|
+
builder.should_receive(:build).and_return(teleport)
|
83
|
+
|
84
|
+
dsl.teleport {}
|
85
|
+
dsl.should have(1).teleports
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/dsl/handler_builder'
|
3
|
+
require 'emory/handlers/stdout_handler'
|
4
|
+
|
5
|
+
module Emory
|
6
|
+
module DSL
|
7
|
+
|
8
|
+
describe HandlerBuilder do
|
9
|
+
|
10
|
+
it "mandates a block needs to be supplied to builder constructor" do
|
11
|
+
proc {
|
12
|
+
HandlerBuilder.new
|
13
|
+
}.should raise_error(HandlerConfigurationBlockMustBeSuppliedException)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "mandates action of type ':all' to be exclusive of other types" do
|
17
|
+
p = proc {
|
18
|
+
name :test_handler
|
19
|
+
implementation ::Emory::Handlers::StdoutHandler
|
20
|
+
events :added, :all
|
21
|
+
}
|
22
|
+
|
23
|
+
builder = HandlerBuilder.new(&p)
|
24
|
+
proc {
|
25
|
+
builder.build
|
26
|
+
}.should raise_error(HandlerActionAllMustBeSingletonException)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "mandates at least one action type to be supplied to 'events'" do
|
30
|
+
p = proc {
|
31
|
+
name :test_handler
|
32
|
+
implementation ::Emory::Handlers::StdoutHandler
|
33
|
+
events
|
34
|
+
}
|
35
|
+
|
36
|
+
builder = HandlerBuilder.new(&p)
|
37
|
+
proc {
|
38
|
+
builder.build
|
39
|
+
}.should raise_error(HandlerActionMustBeSuppliedException)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "mandates 'events' configuration to be supplied to proc" do
|
43
|
+
p = proc {
|
44
|
+
name :test_handler
|
45
|
+
implementation ::Emory::Handlers::StdoutHandler
|
46
|
+
}
|
47
|
+
|
48
|
+
builder = HandlerBuilder.new(&p)
|
49
|
+
proc {
|
50
|
+
builder.build
|
51
|
+
}.should raise_error(HandlerActionMustBeSuppliedException)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "mandates correct handler action types are required to be supplied" do
|
55
|
+
p = proc {
|
56
|
+
name :test_handler
|
57
|
+
implementation ::Emory::Handlers::StdoutHandler
|
58
|
+
events :foo
|
59
|
+
}
|
60
|
+
|
61
|
+
builder = HandlerBuilder.new(&p)
|
62
|
+
proc {
|
63
|
+
builder.build
|
64
|
+
}.should raise_error(HandlerActionUnsupportedException)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "mandates 'name' configuration to be supplied to proc" do
|
68
|
+
p = proc {
|
69
|
+
implementation ::Emory::Handlers::StdoutHandler
|
70
|
+
}
|
71
|
+
|
72
|
+
builder = HandlerBuilder.new(&p)
|
73
|
+
proc {
|
74
|
+
builder.build
|
75
|
+
}.should raise_error(HandlerNameMustBeSuppliedException)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "mandates 'implementation' configuration to be supplied to proc" do
|
79
|
+
p = proc {
|
80
|
+
name :test_handler
|
81
|
+
}
|
82
|
+
|
83
|
+
builder = HandlerBuilder.new(&p)
|
84
|
+
proc {
|
85
|
+
builder.build
|
86
|
+
}.should raise_error(HandlerImplementationMustBeSuppliedException)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "passes the supplied name and options on to the handler's constructor" do
|
90
|
+
p = proc {
|
91
|
+
name :test_handler
|
92
|
+
implementation ::Emory::Handlers::StdoutHandler
|
93
|
+
events :all
|
94
|
+
options host: 'localhost', port: '8080'
|
95
|
+
}
|
96
|
+
|
97
|
+
Emory::Handlers::StdoutHandler.should_receive(:new).with(:test_handler, {host: 'localhost', port: '8080'})
|
98
|
+
|
99
|
+
builder = HandlerBuilder.new(&p)
|
100
|
+
builder.build
|
101
|
+
end
|
102
|
+
|
103
|
+
it "passes the supplied name and empty hash on to the handler's constructor if options configuration is not supplied" do
|
104
|
+
p = proc {
|
105
|
+
name :test_handler
|
106
|
+
implementation ::Emory::Handlers::StdoutHandler
|
107
|
+
events :all
|
108
|
+
}
|
109
|
+
|
110
|
+
Emory::Handlers::StdoutHandler.should_receive(:new).with(:test_handler, {})
|
111
|
+
|
112
|
+
builder = HandlerBuilder.new(&p)
|
113
|
+
builder.build
|
114
|
+
end
|
115
|
+
|
116
|
+
it "with action of type ':all' does not undefine any handler's methods" do
|
117
|
+
p = proc {
|
118
|
+
name :test_handler
|
119
|
+
implementation ::Emory::Handlers::StdoutHandler
|
120
|
+
events :all
|
121
|
+
}
|
122
|
+
|
123
|
+
builder = HandlerBuilder.new(&p)
|
124
|
+
handler = builder.build
|
125
|
+
|
126
|
+
handler.respond_to?(:added).should == true
|
127
|
+
handler.respond_to?(:modified).should == true
|
128
|
+
handler.respond_to?(:removed).should == true
|
129
|
+
end
|
130
|
+
|
131
|
+
it "with all action types does not undefine any handler's methods" do
|
132
|
+
p = proc {
|
133
|
+
name :test_handler
|
134
|
+
implementation ::Emory::Handlers::StdoutHandler
|
135
|
+
events :added, :modified, :removed
|
136
|
+
}
|
137
|
+
|
138
|
+
builder = HandlerBuilder.new(&p)
|
139
|
+
handler = builder.build
|
140
|
+
|
141
|
+
handler.respond_to?(:added).should == true
|
142
|
+
handler.respond_to?(:modified).should == true
|
143
|
+
handler.respond_to?(:removed).should == true
|
144
|
+
end
|
145
|
+
|
146
|
+
it "undefines handler's methods which are not supplied" do
|
147
|
+
p = proc {
|
148
|
+
name :test_handler
|
149
|
+
implementation ::Emory::Handlers::StdoutHandler
|
150
|
+
events :added
|
151
|
+
}
|
152
|
+
|
153
|
+
builder = HandlerBuilder.new(&p)
|
154
|
+
handler = builder.build
|
155
|
+
|
156
|
+
handler.respond_to?(:added).should == true
|
157
|
+
handler.respond_to?(:modified).should == false
|
158
|
+
handler.respond_to?(:removed).should == false
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/dsl/teleport_config_builder'
|
3
|
+
|
4
|
+
module Emory
|
5
|
+
module DSL
|
6
|
+
|
7
|
+
describe TeleportConfigBuilder do
|
8
|
+
|
9
|
+
it "mandates handlers and a block need to be supplied to builder constructor" do
|
10
|
+
proc {
|
11
|
+
TeleportConfigBuilder.new({})
|
12
|
+
}.should raise_error(TeleportConfigurationBlockMustBeSuppliedException)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "mandates a handler reference to be supplied" do
|
16
|
+
p = proc {}
|
17
|
+
|
18
|
+
handlers = {test_handler: Object.new}
|
19
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
20
|
+
proc {
|
21
|
+
builder.build
|
22
|
+
}.should raise_error(HandlerReferenceMustBeSuppliedException)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "mandates an existing handler reference to be supplied" do
|
26
|
+
p = proc {
|
27
|
+
handler :does_not_exist
|
28
|
+
}
|
29
|
+
|
30
|
+
handlers = {test_handler: Object.new}
|
31
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
32
|
+
proc {
|
33
|
+
builder.build
|
34
|
+
}.should raise_error(UndefinedTeleportHandlerException)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "mandates a watched path to be supplied" do
|
38
|
+
p = proc {
|
39
|
+
handler :test_handler
|
40
|
+
}
|
41
|
+
|
42
|
+
handlers = {test_handler: Object.new}
|
43
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
44
|
+
proc {
|
45
|
+
builder.build
|
46
|
+
}.should raise_error(WatchedPathMustBeSuppliedException)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "verifies mandatory configuration settings" do
|
50
|
+
p = proc {
|
51
|
+
handler :test_handler
|
52
|
+
path '/path/to/file'
|
53
|
+
}
|
54
|
+
|
55
|
+
handler = Object.new
|
56
|
+
handlers = {test_handler: handler}
|
57
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
58
|
+
|
59
|
+
teleport = builder.build
|
60
|
+
teleport.watched_path.should == '/path/to/file'
|
61
|
+
teleport.handler.should == handler
|
62
|
+
end
|
63
|
+
|
64
|
+
it "verifies complete configuration settings" do
|
65
|
+
p = proc {
|
66
|
+
handler :test_handler
|
67
|
+
path '/path/to/file'
|
68
|
+
ignore %r{ignored/}
|
69
|
+
filter /\.txt$/
|
70
|
+
}
|
71
|
+
|
72
|
+
handler = Object.new
|
73
|
+
handlers = {test_handler: handler}
|
74
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
75
|
+
|
76
|
+
teleport = builder.build
|
77
|
+
teleport.watched_path.should == '/path/to/file'
|
78
|
+
teleport.handler.should == handler
|
79
|
+
teleport.ignore.should == %r{ignored/}
|
80
|
+
teleport.filter.should == /\.txt$/
|
81
|
+
end
|
82
|
+
|
83
|
+
it "verifies optional 'ignore' configuration setting" do
|
84
|
+
p = proc {
|
85
|
+
handler :test_handler
|
86
|
+
path '/path/to/file'
|
87
|
+
ignore %r{ignored/}
|
88
|
+
}
|
89
|
+
|
90
|
+
handler = Object.new
|
91
|
+
handlers = {test_handler: handler}
|
92
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
93
|
+
|
94
|
+
teleport = builder.build
|
95
|
+
teleport.ignore.should == %r{ignored/}
|
96
|
+
end
|
97
|
+
|
98
|
+
it "verifies optional 'filter' configuration setting" do
|
99
|
+
p = proc {
|
100
|
+
handler :test_handler
|
101
|
+
path '/path/to/file'
|
102
|
+
filter /\.txt$/
|
103
|
+
}
|
104
|
+
|
105
|
+
handler = Object.new
|
106
|
+
handlers = {test_handler: handler}
|
107
|
+
builder = TeleportConfigBuilder.new(handlers, &p)
|
108
|
+
|
109
|
+
teleport = builder.build
|
110
|
+
teleport.filter.should == /\.txt$/
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/handlers/abstract_handler'
|
3
|
+
|
4
|
+
module Emory
|
5
|
+
module Handlers
|
6
|
+
|
7
|
+
describe AbstractHandler do
|
8
|
+
context "is abstract so its method" do
|
9
|
+
let(:handler) { AbstractHandler.new(:test_handler) }
|
10
|
+
|
11
|
+
it "'added' raises NotImplementedError" do
|
12
|
+
proc {
|
13
|
+
handler.added
|
14
|
+
}.should raise_error(NotImplementedError,
|
15
|
+
/This method is not implemented: Emory::Handlers::AbstractHandler#added/)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "'modified' raises NotImplementedError" do
|
19
|
+
proc {
|
20
|
+
handler.modified
|
21
|
+
}.should raise_error(NotImplementedError,
|
22
|
+
/This method is not implemented: Emory::Handlers::AbstractHandler#modified/)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "'removed' raises NotImplementedError" do
|
26
|
+
proc {
|
27
|
+
handler.removed
|
28
|
+
}.should raise_error(NotImplementedError,
|
29
|
+
/This method is not implemented: Emory::Handlers::AbstractHandler#removed/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'emory/handlers/stdout_handler'
|
3
|
+
|
4
|
+
module Emory
|
5
|
+
module Handlers
|
6
|
+
|
7
|
+
describe StdoutHandler do
|
8
|
+
context "works with standard output" do
|
9
|
+
let(:handler) { StdoutHandler.new(:test_handler) }
|
10
|
+
|
11
|
+
it "'added' just calls 'puts' with right params" do
|
12
|
+
handler.should_receive(:puts).with(":test_handler ~> The file '/path/to/file' was 'added'")
|
13
|
+
handler.added '/path/to/file'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "'modified' just calls 'puts' with right params" do
|
17
|
+
handler.should_receive(:puts).with(":test_handler ~> The file '/path/to/file' was 'modified'")
|
18
|
+
handler.modified '/path/to/file'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "'removed' just calls 'puts' with right params" do
|
22
|
+
handler.should_receive(:puts).with(":test_handler ~> The file '/path/to/file' was 'removed'")
|
23
|
+
handler.removed '/path/to/file'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'listen'
|
3
|
+
require 'pathname'
|
4
|
+
require 'emory/runner'
|
5
|
+
require 'emory/dsl/dsl'
|
6
|
+
require 'emory/teleport_config'
|
7
|
+
require 'emory/handlers/stdout_handler'
|
8
|
+
|
9
|
+
module Emory
|
10
|
+
|
11
|
+
describe Runner do
|
12
|
+
context "class object" do
|
13
|
+
it "starts the config file location process, creates necessary listener with absolute path and joins current thread" do
|
14
|
+
dsl = DSL::Dsl.new
|
15
|
+
teleport = TeleportConfig.new
|
16
|
+
teleport.watched_path = 'watched_path'
|
17
|
+
teleport.handler = Handlers::StdoutHandler.new(:handler_name)
|
18
|
+
teleport.ignore = 'ignore_path'
|
19
|
+
teleport.filter = 'filter_expression'
|
20
|
+
dsl.teleports << teleport
|
21
|
+
|
22
|
+
path_to_config_file = '/path/to/config/file'
|
23
|
+
ConfigurationFile.stub(:locate => path_to_config_file)
|
24
|
+
File.stub(:read).with(path_to_config_file).and_return('contents')
|
25
|
+
DSL::Dsl.stub(:instance_eval_emoryfile).with('contents', path_to_config_file).and_return(dsl)
|
26
|
+
|
27
|
+
Pathname.any_instance.stub(:absolute?).and_return(true)
|
28
|
+
|
29
|
+
mock_listener = double("listener")
|
30
|
+
Listen.stub(:to).with('watched_path').and_return(mock_listener)
|
31
|
+
mock_listener.should_receive(:ignore).with(teleport.ignore)
|
32
|
+
mock_listener.should_receive(:filter).with(teleport.filter)
|
33
|
+
mock_listener.should_receive(:change)
|
34
|
+
mock_listener.should_receive(:start).with(false)
|
35
|
+
|
36
|
+
mock_thread = double("thread")
|
37
|
+
Thread.stub(:current => mock_thread)
|
38
|
+
mock_thread.should_receive(:join)
|
39
|
+
|
40
|
+
Runner.start
|
41
|
+
end
|
42
|
+
|
43
|
+
it "starts the config file location process, creates necessary listener with relative path and joins current thread" do
|
44
|
+
dsl = DSL::Dsl.new
|
45
|
+
teleport = TeleportConfig.new
|
46
|
+
teleport.watched_path = 'watched_path'
|
47
|
+
teleport.handler = Handlers::StdoutHandler.new(:handler_name)
|
48
|
+
teleport.ignore = 'ignore_path'
|
49
|
+
teleport.filter = 'filter_expression'
|
50
|
+
dsl.teleports << teleport
|
51
|
+
|
52
|
+
path_to_config_file = '/path/to/config/file'
|
53
|
+
ConfigurationFile.stub(:locate => path_to_config_file)
|
54
|
+
File.stub(:read).with(path_to_config_file).and_return('contents')
|
55
|
+
DSL::Dsl.stub(:instance_eval_emoryfile).with('contents', path_to_config_file).and_return(dsl)
|
56
|
+
|
57
|
+
Pathname.any_instance.stub(:absolute?).and_return(false)
|
58
|
+
File.should_receive(:expand_path).with('watched_path', '/path/to/config').and_return('/path/to/config/watched_path')
|
59
|
+
|
60
|
+
mock_listener = double("listener")
|
61
|
+
Listen.stub(:to).with('/path/to/config/watched_path').and_return(mock_listener)
|
62
|
+
mock_listener.should_receive(:ignore).with(teleport.ignore)
|
63
|
+
mock_listener.should_receive(:filter).with(teleport.filter)
|
64
|
+
mock_listener.should_receive(:change)
|
65
|
+
mock_listener.should_receive(:start).with(false)
|
66
|
+
|
67
|
+
mock_thread = double("thread")
|
68
|
+
Thread.stub(:current => mock_thread)
|
69
|
+
mock_thread.should_receive(:join)
|
70
|
+
|
71
|
+
Runner.start
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED