bane 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +16 -6
- data/Rakefile +1 -1
- data/TODO +5 -8
- data/bin/bane +4 -12
- data/examples/multiple_behaviors.rb +7 -6
- data/examples/readme_example.rb +2 -1
- data/examples/single_behavior.rb +2 -1
- data/lib/bane.rb +18 -5
- data/lib/bane/arguments_parser.rb +73 -0
- data/lib/bane/behavior_maker.rb +39 -0
- data/lib/bane/behaviors/responders/close_after_pause.rb +21 -0
- data/lib/bane/behaviors/responders/close_immediately.rb +14 -0
- data/lib/bane/behaviors/responders/deluge_response.rb +27 -0
- data/lib/bane/behaviors/responders/echo_response.rb +16 -0
- data/lib/bane/behaviors/responders/exported.rb +9 -0
- data/lib/bane/behaviors/responders/fixed_response.rb +25 -0
- data/lib/bane/behaviors/responders/for_each_line.rb +18 -0
- data/lib/bane/behaviors/responders/http_refuse_all_credentials.rb +31 -0
- data/lib/bane/behaviors/responders/never_respond.rb +27 -0
- data/lib/bane/behaviors/responders/newline_response.rb +18 -0
- data/lib/bane/behaviors/responders/random_response.rb +24 -0
- data/lib/bane/behaviors/responders/slow_response.rb +32 -0
- data/lib/bane/behaviors/servers/exported.rb +18 -0
- data/lib/bane/behaviors/servers/responder_server.rb +50 -0
- data/lib/bane/behaviors/servers/timeout_in_listen_queue.rb +51 -0
- data/lib/bane/command_line_configuration.rb +22 -79
- data/lib/bane/extensions.rb +7 -0
- data/test/bane/acceptance_test.rb +65 -0
- data/test/bane/arguments_parser_test.rb +76 -0
- data/test/bane/bane_test.rb +12 -0
- data/test/bane/behaviors/responders/close_after_pause_test.rb +30 -0
- data/test/bane/behaviors/responders/close_immediately_test.rb +14 -0
- data/test/bane/behaviors/responders/deluge_response_test.rb +20 -0
- data/test/bane/behaviors/responders/echo_response_test.rb +16 -0
- data/test/bane/behaviors/responders/fixed_response_test.rb +14 -0
- data/test/bane/behaviors/responders/for_each_line_test.rb +29 -0
- data/test/bane/behaviors/responders/http_refuse_all_credentials_test.rb +18 -0
- data/test/bane/behaviors/responders/never_respond_test.rb +31 -0
- data/test/bane/behaviors/responders/newline_response_test.rb +14 -0
- data/test/bane/behaviors/responders/random_response_test.rb +15 -0
- data/test/bane/behaviors/responders/slow_response_test.rb +21 -0
- data/test/bane/behaviors/servers/responder_server_test.rb +77 -0
- data/test/bane/behaviors/servers/timeout_in_listen_queue_test.rb +23 -0
- data/test/bane/command_line_configuration_test.rb +54 -72
- data/test/bane/extensions_test.rb +17 -0
- data/test/bane/fake_connection_test.rb +1 -1
- data/test/bane/launchable_role_tests.rb +20 -0
- data/test/bane/naive_http_response_test.rb +1 -1
- data/test/test_helper.rb +42 -1
- metadata +143 -99
- data/lib/bane/behavior_server.rb +0 -47
- data/lib/bane/behaviors.rb +0 -171
- data/lib/bane/compatibility.rb +0 -36
- data/lib/bane/configuration_parser.rb +0 -89
- data/lib/bane/service_registry.rb +0 -21
- data/test/bane/behavior_server_test.rb +0 -59
- data/test/bane/behaviors_test.rb +0 -135
- data/test/bane/configuration_parser_test.rb +0 -111
- data/test/bane/integration_test.rb +0 -92
- data/test/bane/service_registry_test.rb +0 -20
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class ArgumentsParserTest < Test::Unit::TestCase
|
4
|
+
include Bane
|
5
|
+
|
6
|
+
# Parsing arguments (uses the isolated ArgumentsParser object)
|
7
|
+
|
8
|
+
def test_parses_the_port
|
9
|
+
config = parse(["3000", IRRELEVANT_BEHAVIOR])
|
10
|
+
assert_equal 3000, config.port
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_parses_the_behaviors
|
14
|
+
config = parse([IRRELEVANT_PORT, 'NeverRespond', 'EchoResponse'])
|
15
|
+
assert_equal ['NeverRespond', 'EchoResponse'], config.behaviors
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_host_defaults_to_localhost_if_not_specified
|
19
|
+
config = parse([IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
20
|
+
assert_equal '127.0.0.1', config.host
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_dash_l_option_sets_listen_host_to_localhost
|
24
|
+
assert_parses_host(Behaviors::Servers::LOCALHOST, ['-l', IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_listen_on_localhost_sets_listen_host_to_localhost
|
28
|
+
assert_parses_host(Behaviors::Servers::LOCALHOST, ['--listen-on-localhost', IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_dash_a_option_sets_listen_host_to_all_interfaces
|
32
|
+
assert_parses_host(Behaviors::Servers::ALL_INTERFACES, ['-a', IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_listen_on_all_hosts_option_sets_listen_host_to_all_interfaces
|
36
|
+
assert_parses_host(Behaviors::Servers::ALL_INTERFACES, ['--listen-on-all-hosts', IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_usage_message_includes_known_makeables_in_alphabetical_order
|
40
|
+
usage = ArgumentsParser.new(['makeable2', 'makeable1']).usage
|
41
|
+
assert_match /makeable1/i, usage, 'Should have included all known makeables'
|
42
|
+
assert_match /makeable2/i, usage, 'Should have included all known makeables'
|
43
|
+
assert_match /makeable1\W+makeable2/i, usage, 'Should have been in alphabetical order'
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_no_arguments_fail_with
|
47
|
+
assert_invalid_arguments_fail_matching_message([], /missing arguments/i)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_non_integer_port_fails_with_error_message
|
51
|
+
assert_invalid_arguments_fail_matching_message(['text_instead_of_an_integer'], /Invalid Port Number/i)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_invalid_option_fails_with_error_message
|
55
|
+
assert_invalid_arguments_fail_matching_message(['--unknown-option', IRRELEVANT_PORT], /Invalid Option/i)
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse(arguments)
|
59
|
+
ArgumentsParser.new(["makeable1", "makeable2"]).parse(arguments)
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_parses_host(expected_host, arguments)
|
63
|
+
config = parse(arguments)
|
64
|
+
assert_equal expected_host, config.host
|
65
|
+
end
|
66
|
+
|
67
|
+
def assert_invalid_arguments_fail_matching_message(arguments, message_matcher)
|
68
|
+
begin
|
69
|
+
parse(arguments)
|
70
|
+
flunk "Should have thrown an error"
|
71
|
+
rescue ConfigurationError => ce
|
72
|
+
assert_match message_matcher, ce.message
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class BaneTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_includes_responders_and_servers_in_all_makeables
|
6
|
+
all_names = Bane.find_makeables.keys
|
7
|
+
|
8
|
+
assert all_names.include?('NeverRespond'), "Expected 'NeverRespond' responder to be in #{all_names}"
|
9
|
+
assert all_names.include?('TimeoutInListenQueue'), "Expected 'TimeoutInListenQueue' server to be in #{all_names}"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
require 'mocha/setup'
|
3
|
+
|
4
|
+
class CloseAfterPauseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include Bane::Behaviors::Responders
|
7
|
+
include BehaviorTestHelpers
|
8
|
+
|
9
|
+
def test_sleeps_30_seconds_by_default
|
10
|
+
server = CloseAfterPause.new
|
11
|
+
server.expects(:sleep).with(30)
|
12
|
+
|
13
|
+
query_server(server)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sleeps_specified_number_of_seconds
|
17
|
+
server = CloseAfterPause.new(duration: 1)
|
18
|
+
server.expects(:sleep).with(1)
|
19
|
+
|
20
|
+
query_server(server)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_sends_nothing
|
24
|
+
server = CloseAfterPause.new
|
25
|
+
server.stubs(:sleep)
|
26
|
+
|
27
|
+
query_server(server)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class CloseImmediatelyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_no_response
|
9
|
+
query_server(CloseImmediately.new)
|
10
|
+
|
11
|
+
assert_empty_response
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class DelugeResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_one_million_bytes_by_default
|
9
|
+
query_server(DelugeResponse.new)
|
10
|
+
|
11
|
+
assert_response_length 1_000_000
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_sends_the_specified_number_of_bytes
|
15
|
+
query_server(DelugeResponse.new(length: 1))
|
16
|
+
|
17
|
+
assert_response_length 1
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class EchoResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_returns_received_characters
|
9
|
+
fake_connection.will_send("Hello, echo!")
|
10
|
+
|
11
|
+
query_server(EchoResponse.new)
|
12
|
+
|
13
|
+
assert_equal "Hello, echo!", response
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class FixedResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_the_specified_message
|
9
|
+
query_server(FixedResponse.new(message: "Test Message"))
|
10
|
+
|
11
|
+
assert_equal "Test Message", response
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
require 'mocha/setup'
|
3
|
+
|
4
|
+
class ForEachLineTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include Bane::Behaviors::Responders
|
7
|
+
include BehaviorTestHelpers
|
8
|
+
|
9
|
+
def test_reads_a_line_before_responding_with_parent_behavior
|
10
|
+
server = SayHelloForEachLineBehavior.new
|
11
|
+
|
12
|
+
fake_connection.will_send "irrelevant\n"
|
13
|
+
|
14
|
+
query_server(server)
|
15
|
+
assert_equal "Hello", response
|
16
|
+
|
17
|
+
assert fake_connection.read_all_queries?
|
18
|
+
end
|
19
|
+
|
20
|
+
class SayHelloBehavior
|
21
|
+
def serve(io)
|
22
|
+
io.write('Hello')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class SayHelloForEachLineBehavior < SayHelloBehavior
|
27
|
+
include Bane::Behaviors::Responders::ForEachLine
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class HttpRefuseAllCredentialsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_401_response_code
|
9
|
+
fake_connection.will_send("GET /some/irrelevant/path HTTP/1.1")
|
10
|
+
|
11
|
+
server = HttpRefuseAllCredentials.new
|
12
|
+
query_server(server)
|
13
|
+
|
14
|
+
assert fake_connection.read_all_queries?, "Should have read the HTTP query before sending response"
|
15
|
+
assert_match /HTTP\/1.1 401 Unauthorized/, response, 'Should have responded with the 401 response code'
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class NeverRespondTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
include ServerTestHelpers
|
8
|
+
|
9
|
+
LONG_MESSAGE = 'x'*(1024*5)
|
10
|
+
|
11
|
+
def test_does_not_send_a_response
|
12
|
+
server = NeverRespond.new
|
13
|
+
|
14
|
+
query_server(server)
|
15
|
+
assert_empty_response
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_disconnects_after_client_closes_connection
|
19
|
+
run_server(Bane::Behaviors::Servers::ResponderServer.new(0, NeverRespond.new)) do |server|
|
20
|
+
client = TCPSocket.new('localhost', server.port)
|
21
|
+
sleep 3
|
22
|
+
client.write LONG_MESSAGE
|
23
|
+
client.close
|
24
|
+
|
25
|
+
sleep 0.1
|
26
|
+
|
27
|
+
assert_equal 0, server.connections
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class NewlineResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_only_a_newline_character
|
9
|
+
query_server(NewlineResponse.new)
|
10
|
+
|
11
|
+
assert_equal "\n", response
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
class RandomResponseTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Bane::Behaviors::Responders
|
6
|
+
include BehaviorTestHelpers
|
7
|
+
|
8
|
+
def test_sends_a_nonempty_response
|
9
|
+
query_server(RandomResponse.new)
|
10
|
+
|
11
|
+
assert (!response.empty?), "Should have served a nonempty response"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
require 'mocha/setup'
|
3
|
+
|
4
|
+
class SlowResponseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include Bane::Behaviors::Responders
|
7
|
+
include BehaviorTestHelpers
|
8
|
+
|
9
|
+
def test_pauses_between_sending_each_character
|
10
|
+
message = "Hi!"
|
11
|
+
delay = 0.5
|
12
|
+
|
13
|
+
server = SlowResponse.new(pause_duration: delay, message: message)
|
14
|
+
server.expects(:sleep).with(delay).at_least(message.length)
|
15
|
+
|
16
|
+
query_server(server)
|
17
|
+
|
18
|
+
assert_equal message, response
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
require 'mocha/setup'
|
3
|
+
|
4
|
+
class ResponderServerTest < Test::Unit::TestCase
|
5
|
+
include LaunchableRoleTests
|
6
|
+
|
7
|
+
include Bane
|
8
|
+
include Bane::Behaviors::Servers
|
9
|
+
|
10
|
+
IRRELEVANT_IO_STREAM = nil
|
11
|
+
IRRELEVANT_OPTIONS = {}
|
12
|
+
IRRELEVANT_HOST = '1.1.1.1'
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@object = ResponderServer.new(IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_initializes_server_on_specified_port
|
19
|
+
server = ResponderServer.new(6000, IRRELEVANT_BEHAVIOR)
|
20
|
+
assert_equal 6000, server.port
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_initializes_server_on_specified_hostname
|
24
|
+
server = ResponderServer.new(IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR, 'hostname')
|
25
|
+
assert_equal 'hostname', server.host
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_delegates_serve_call_to_responder
|
29
|
+
io = mock
|
30
|
+
responder = mock
|
31
|
+
server = ResponderServer.new(IRRELEVANT_PORT, responder)
|
32
|
+
|
33
|
+
responder.expects(:serve).with(io)
|
34
|
+
|
35
|
+
server.serve(io)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_connection_log_messages_use_short_behavior_name_to_shorten_log_messages
|
39
|
+
[:connecting, :disconnecting].each do |method|
|
40
|
+
assert_log_message_uses_short_behavior_name_for(method) do |server|
|
41
|
+
server.send(method, stub_everything(peeraddr: [127, 0, 0, 1]))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_start_stop_log_messages_use_short_behavior_name_to_shorten_log_messages
|
47
|
+
[:starting, :stopping].each do |method|
|
48
|
+
assert_log_message_uses_short_behavior_name_for(method) do |server|
|
49
|
+
server.send(method)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def assert_log_message_uses_short_behavior_name_for(method)
|
55
|
+
logger = StringIO.new
|
56
|
+
server = ResponderServer.new(IRRELEVANT_PORT, Bane::Behaviors::Responders::SampleForTesting.new)
|
57
|
+
server.stdlog = logger
|
58
|
+
|
59
|
+
yield server
|
60
|
+
|
61
|
+
assert_match /SampleForTesting/, logger.string, "Log for #{method} should contain class short name"
|
62
|
+
assert_no_match /Behaviors::Responders::SampleForTesting/, logger.string, "Log for #{method} should not contain expanded module name"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
module Bane
|
68
|
+
module Behaviors
|
69
|
+
module Responders
|
70
|
+
class SampleForTesting
|
71
|
+
def serve(io)
|
72
|
+
io.puts('Hello')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class TimeoutInListenQueueTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include LaunchableRoleTests
|
7
|
+
include ServerTestHelpers
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Bane::Behaviors::Servers::TimeoutInListenQueue.make(IRRELEVANT_PORT, Bane::Behaviors::Servers::LOCALHOST)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_never_connects
|
14
|
+
run_server(Bane::Behaviors::Servers::TimeoutInListenQueue.make(port, Bane::Behaviors::Servers::LOCALHOST)) do
|
15
|
+
assert_raise(Errno::ECONNREFUSED) { TCPSocket.new('localhost', port) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def port
|
20
|
+
4001
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -1,100 +1,82 @@
|
|
1
|
-
|
2
|
-
require 'mocha'
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'mocha/setup'
|
3
3
|
|
4
4
|
class CommandLineConfigurationTest < Test::Unit::TestCase
|
5
5
|
include Bane
|
6
6
|
|
7
|
-
|
7
|
+
# Creation tests (uses a cluster of objects starting at the top-level CommandLineConfiguration)
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def test_creates_all_known_behavior_if_only_port_specified
|
16
|
-
expect_server_created_with :port => 4000, :behavior => Behaviors::CloseImmediately
|
17
|
-
expect_server_created_with :port => 4001, :behavior => Behaviors::NeverRespond
|
18
|
-
|
19
|
-
ServiceRegistry.stubs(:all_servers).returns([Behaviors::CloseImmediately, Behaviors::NeverRespond])
|
20
|
-
|
21
|
-
create_configuration_for([4000])
|
9
|
+
def test_creates_specified_makeable_on_given_port
|
10
|
+
behaviors = process arguments: [3000, 'ThingA'],
|
11
|
+
configuration: { 'ThingA' => SimpleMaker.new('ThingA'),
|
12
|
+
'ThingB' => SimpleMaker.new('ThingB') }
|
13
|
+
assert_equal 1, behaviors.size, "Wrong number of behaviors, got #{behaviors}"
|
14
|
+
assert_makeable_created(behaviors.first, port: 3000, name: 'ThingA')
|
22
15
|
end
|
23
16
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
17
|
+
def test_creates_multiple_makeables_on_increasing_ports
|
18
|
+
behaviors = process arguments: [4000, 'ThingA', 'ThingB'],
|
19
|
+
configuration: {'ThingA' => SimpleMaker.new('ThingA'),
|
20
|
+
'ThingB' => SimpleMaker.new('ThingB') }
|
27
21
|
|
28
|
-
|
22
|
+
assert_equal 2, behaviors.size, "Wrong number of behaviors, got #{behaviors}"
|
23
|
+
assert_makeable_created(behaviors.first, port: 4000, name: 'ThingA')
|
24
|
+
assert_makeable_created(behaviors.last, port: 4000 + 1, name: 'ThingB')
|
29
25
|
end
|
30
26
|
|
31
|
-
def
|
32
|
-
|
27
|
+
def test_creates_all_known_makeables_in_alphabetical_order_if_only_port_specified
|
28
|
+
behaviors = process arguments: [4000],
|
29
|
+
configuration: { 'ThingB' => SimpleMaker.new('ThingB'),
|
30
|
+
'ThingC' => SimpleMaker.new('ThingC'),
|
31
|
+
'ThingA' => SimpleMaker.new('ThingA') }
|
33
32
|
|
34
|
-
|
33
|
+
assert_equal 3, behaviors.size, "Wrong number of behaviors created, got #{behaviors}"
|
34
|
+
assert_equal 'ThingA', behaviors[0].name
|
35
|
+
assert_equal 'ThingB', behaviors[1].name
|
36
|
+
assert_equal 'ThingC', behaviors[2].name
|
35
37
|
end
|
36
38
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
def process(options)
|
40
|
+
arguments = options.fetch(:arguments)
|
41
|
+
makeables = options.fetch(:configuration)
|
42
|
+
CommandLineConfiguration.new(makeables).process(arguments) { |errors| raise errors }
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
create_configuration_for(["-a", IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_listen_on_all_hosts_option_sets_listen_host_to_all_interfaces
|
50
|
-
expect_server_created_with :host => BehaviorServer::ALL_INTERFACES
|
51
|
-
|
52
|
-
create_configuration_for(["--listen-on-all-hosts", IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR])
|
45
|
+
def assert_makeable_created(behaviors, parameters)
|
46
|
+
assert_equal parameters.fetch(:port), behaviors.port
|
47
|
+
assert_equal parameters.fetch(:name), behaviors.name
|
53
48
|
end
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
class SimpleMaker
|
51
|
+
attr_reader :name, :port, :host
|
52
|
+
def initialize(name)
|
53
|
+
@name = name
|
54
|
+
end
|
55
|
+
|
56
|
+
def make(port, host)
|
57
|
+
@port = port
|
58
|
+
@host = host
|
59
|
+
self
|
60
|
+
end
|
58
61
|
end
|
59
62
|
|
60
|
-
|
61
|
-
assert_invaild_arguments_fail_matching_message(["text_instead_of_an_integer"], /Invalid Port Number/i,
|
62
|
-
"Should have indicated the port was invalid.")
|
63
|
-
end
|
63
|
+
# Failure tests (uses a cluster of objects starting at the top-level CommandLineConfiguration)
|
64
64
|
|
65
|
-
def
|
66
|
-
|
67
|
-
"Should have indicated the given behavior is unknown.")
|
65
|
+
def test_unknown_behavior_fails_with_message
|
66
|
+
assert_invalid_arguments_fail_matching_message([IRRELEVANT_PORT, 'AnUnknownBehavior'], /Unknown Behavior/i)
|
68
67
|
end
|
69
68
|
|
70
69
|
def test_invalid_option_fails_with_error_message
|
71
|
-
|
72
|
-
"Should have indicated the --uknown-option switch was unknown.")
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def create_configuration_for(array)
|
79
|
-
CommandLineConfiguration.new().parse(array)
|
70
|
+
assert_invalid_arguments_fail_matching_message(['--unknown-option', IRRELEVANT_PORT], /Invalid Option/i)
|
80
71
|
end
|
81
72
|
|
82
|
-
def
|
83
|
-
|
73
|
+
def assert_invalid_arguments_fail_matching_message(arguments, message_matcher)
|
74
|
+
block_called = false
|
75
|
+
CommandLineConfiguration.new({}).process(arguments) do |error_message|
|
76
|
+
block_called = true
|
77
|
+
assert_match message_matcher, error_message
|
78
|
+
end
|
79
|
+
assert block_called, "Expected invalid arguments to invoke the failure block"
|
84
80
|
end
|
85
81
|
|
86
|
-
def expect_server_created_with(arguments)
|
87
|
-
arguments = { :port => anything(), :host => anything() }.merge(arguments)
|
88
|
-
behavior_matcher = arguments[:behavior] ? instance_of(arguments[:behavior]) : anything()
|
89
|
-
BehaviorServer.expects(:new).with(arguments[:port], behavior_matcher, arguments[:host])
|
90
|
-
end
|
91
|
-
|
92
|
-
def assert_invaild_arguments_fail_matching_message(arguments, message_matcher, assertion_failure_message)
|
93
|
-
create_configuration_for(arguments)
|
94
|
-
fail "Should have failed"
|
95
|
-
rescue ConfigurationError => ce
|
96
|
-
assert_match(message_matcher, ce.message, assertion_failure_message)
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
82
|
end
|