bane 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +5 -13
  2. data/HISTORY.md +49 -0
  3. data/LICENSE +1 -1
  4. data/README.md +2 -2
  5. data/lib/bane/arguments_parser.rb +2 -0
  6. data/lib/bane/behavior_maker.rb +5 -3
  7. data/lib/bane/behaviors/responders/close_after_pause.rb +2 -0
  8. data/lib/bane/behaviors/responders/close_immediately.rb +2 -0
  9. data/lib/bane/behaviors/responders/deluge_response.rb +2 -0
  10. data/lib/bane/behaviors/responders/echo_response.rb +2 -0
  11. data/lib/bane/behaviors/responders/exported.rb +2 -0
  12. data/lib/bane/behaviors/responders/fixed_response.rb +2 -0
  13. data/lib/bane/behaviors/responders/for_each_line.rb +2 -0
  14. data/lib/bane/behaviors/responders/http_refuse_all_credentials.rb +2 -0
  15. data/lib/bane/behaviors/responders/never_respond.rb +2 -0
  16. data/lib/bane/behaviors/responders/newline_response.rb +2 -0
  17. data/lib/bane/behaviors/responders/random_response.rb +2 -0
  18. data/lib/bane/behaviors/responders/slow_response.rb +2 -0
  19. data/lib/bane/behaviors/servers/exported.rb +2 -0
  20. data/lib/bane/behaviors/servers/responder_server.rb +2 -0
  21. data/lib/bane/behaviors/servers/timeout_in_listen_queue.rb +2 -0
  22. data/lib/bane/command_line_configuration.rb +2 -0
  23. data/lib/bane/extensions.rb +2 -0
  24. data/lib/bane/launcher.rb +2 -0
  25. data/lib/bane/naive_http_response.rb +2 -0
  26. data/lib/bane/version.rb +5 -0
  27. data/lib/bane.rb +2 -0
  28. metadata +35 -98
  29. data/Rakefile +0 -51
  30. data/examples/multiple_behaviors.rb +0 -25
  31. data/examples/readme_example.rb +0 -10
  32. data/examples/single_behavior.rb +0 -19
  33. data/test/bane/acceptance_test.rb +0 -65
  34. data/test/bane/arguments_parser_test.rb +0 -76
  35. data/test/bane/bane_test.rb +0 -12
  36. data/test/bane/behaviors/responders/close_after_pause_test.rb +0 -30
  37. data/test/bane/behaviors/responders/close_immediately_test.rb +0 -14
  38. data/test/bane/behaviors/responders/deluge_response_test.rb +0 -20
  39. data/test/bane/behaviors/responders/echo_response_test.rb +0 -16
  40. data/test/bane/behaviors/responders/fixed_response_test.rb +0 -14
  41. data/test/bane/behaviors/responders/for_each_line_test.rb +0 -29
  42. data/test/bane/behaviors/responders/http_refuse_all_credentials_test.rb +0 -18
  43. data/test/bane/behaviors/responders/never_respond_test.rb +0 -31
  44. data/test/bane/behaviors/responders/newline_response_test.rb +0 -14
  45. data/test/bane/behaviors/responders/random_response_test.rb +0 -15
  46. data/test/bane/behaviors/responders/slow_response_test.rb +0 -21
  47. data/test/bane/behaviors/servers/responder_server_test.rb +0 -77
  48. data/test/bane/behaviors/servers/timeout_in_listen_queue_test.rb +0 -23
  49. data/test/bane/command_line_configuration_test.rb +0 -82
  50. data/test/bane/extensions_test.rb +0 -17
  51. data/test/bane/fake_connection_test.rb +0 -34
  52. data/test/bane/launchable_role_tests.rb +0 -20
  53. data/test/bane/naive_http_response_test.rb +0 -69
  54. data/test/test_helper.rb +0 -71
@@ -1,76 +0,0 @@
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
@@ -1,12 +0,0 @@
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
@@ -1,30 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,20 +0,0 @@
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
@@ -1,16 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,29 +0,0 @@
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
@@ -1,18 +0,0 @@
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
@@ -1,31 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,15 +0,0 @@
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
-
@@ -1,21 +0,0 @@
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
@@ -1,77 +0,0 @@
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
@@ -1,23 +0,0 @@
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,82 +0,0 @@
1
- require_relative '../test_helper'
2
- require 'mocha/setup'
3
-
4
- class CommandLineConfigurationTest < Test::Unit::TestCase
5
- include Bane
6
-
7
- # Creation tests (uses a cluster of objects starting at the top-level CommandLineConfiguration)
8
-
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')
15
- end
16
-
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') }
21
-
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')
25
- end
26
-
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') }
32
-
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
37
- end
38
-
39
- def process(options)
40
- arguments = options.fetch(:arguments)
41
- makeables = options.fetch(:configuration)
42
- CommandLineConfiguration.new(makeables).process(arguments) { |errors| raise errors }
43
- end
44
-
45
- def assert_makeable_created(behaviors, parameters)
46
- assert_equal parameters.fetch(:port), behaviors.port
47
- assert_equal parameters.fetch(:name), behaviors.name
48
- end
49
-
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
61
- end
62
-
63
- # Failure tests (uses a cluster of objects starting at the top-level CommandLineConfiguration)
64
-
65
- def test_unknown_behavior_fails_with_message
66
- assert_invalid_arguments_fail_matching_message([IRRELEVANT_PORT, 'AnUnknownBehavior'], /Unknown Behavior/i)
67
- end
68
-
69
- def test_invalid_option_fails_with_error_message
70
- assert_invalid_arguments_fail_matching_message(['--unknown-option', IRRELEVANT_PORT], /Invalid Option/i)
71
- end
72
-
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"
80
- end
81
-
82
- end
@@ -1,17 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- class ExtensionsTest < Test::Unit::TestCase
4
- def test_unqualified_name_removes_module_path
5
- assert_equal 'String', String.unqualified_name
6
- assert_equal 'NestedClass', TopModule::NestedClass.unqualified_name
7
- assert_equal 'DoublyNestedClass', TopModule::NestedModule::DoublyNestedClass.unqualified_name
8
- end
9
- end
10
-
11
- module TopModule
12
- class NestedClass; end
13
-
14
- module NestedModule
15
- class DoublyNestedClass; end
16
- end
17
- end
@@ -1,34 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- class FakeConnectionTest < Test::Unit::TestCase
4
-
5
- def setup
6
- @fake_connection = FakeConnection.new
7
- end
8
-
9
- def test_fake_connection_returns_nil_if_no_commands_to_read
10
- assert_nil @fake_connection.gets
11
- end
12
-
13
- def test_fake_connection_reports_when_one_command_set_and_read
14
- @fake_connection.will_send("Command #1")
15
-
16
- @fake_connection.gets
17
-
18
- assert @fake_connection.read_all_queries?, "Should have read all queries"
19
- end
20
-
21
- def test_fake_connection_reports_when_all_commands_read
22
- @fake_connection.will_send("Command #1")
23
- @fake_connection.will_send("Command #2")
24
-
25
- @fake_connection.gets
26
-
27
- assert !@fake_connection.read_all_queries?, "Did not read all queries yet"
28
-
29
- @fake_connection.gets
30
-
31
- assert @fake_connection.read_all_queries?, "Should have read all queries"
32
- end
33
-
34
- end
@@ -1,20 +0,0 @@
1
- module LaunchableRoleTests
2
-
3
- # Verify the contract required for Launcher
4
-
5
- def test_responds_to_start
6
- assert_respond_to(@object, :start)
7
- end
8
-
9
- def test_responds_to_stop
10
- assert_respond_to(@object, :stop)
11
- end
12
-
13
- def test_responds_to_join
14
- assert_respond_to(@object, :join)
15
- end
16
-
17
- def test_responds_to_stdlog
18
- assert_respond_to(@object, :stdlog=)
19
- end
20
- end
@@ -1,69 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- class NaiveHttpResponseTest < Test::Unit::TestCase
4
-
5
- IRRELEVANT_RESPONSE_CODE = "999"
6
- IRRELEVANT_RESPONSE_DESCRIPTION = "Irrelevant description"
7
- IRRELEVANT_CONTENT_TYPE = "irrelevant content type"
8
- IRRELEVANT_BODY = "irrelevant body"
9
-
10
- def test_should_send_http_format_string
11
- response = response_for("200", "OK", IRRELEVANT_CONTENT_TYPE, IRRELEVANT_BODY)
12
- assert_equal "HTTP/1.1 200 OK\r\n", response.lines.first, "First line should be HTTP status"
13
- end
14
-
15
- def test_should_include_date
16
- assert_match /Date: .*/, any_response, 'Should have included a Date header'
17
- end
18
-
19
- def test_should_set_content_type
20
- response = response_for(IRRELEVANT_RESPONSE_CODE,
21
- IRRELEVANT_RESPONSE_DESCRIPTION,
22
- "text/xml",
23
- IRRELEVANT_BODY)
24
- assert_match /Content-Type: text\/xml/, response, 'Should have included content type'
25
- end
26
-
27
- def test_should_set_content_length_as_length_of_body_in_bytes
28
- message = "Hello, there!"
29
- response = response_for(IRRELEVANT_RESPONSE_CODE,
30
- IRRELEVANT_RESPONSE_DESCRIPTION,
31
- IRRELEVANT_CONTENT_TYPE,
32
- message)
33
-
34
- assert_match /Content-Length: #{message.length}/, response, 'Should have included content length'
35
- end
36
-
37
- def test_should_include_newline_between_headers_and_body
38
- message = "This is some body content."
39
- response = response_for(IRRELEVANT_RESPONSE_CODE,
40
- IRRELEVANT_RESPONSE_DESCRIPTION,
41
- IRRELEVANT_CONTENT_TYPE,
42
- message)
43
-
44
- response_lines = response.lines.to_a
45
- index_of_body_start = response_lines.index(message)
46
- line_before_body = response_lines[index_of_body_start - 1]
47
- assert line_before_body.strip.empty?, "Should have had blank line before the body"
48
- end
49
-
50
- def test_should_include_the_body_at_the_end_of_the_response
51
- message = "This is some body content."
52
- response = response_for(IRRELEVANT_RESPONSE_CODE,
53
- IRRELEVANT_RESPONSE_DESCRIPTION,
54
- IRRELEVANT_CONTENT_TYPE,
55
- message)
56
- assert_match /#{message}$/, response, "Should have ended the response with the body content"
57
- end
58
-
59
- private
60
-
61
- def response_for(response_code, response_description, content_type, body)
62
- NaiveHttpResponse.new(response_code, response_description, content_type, body).to_s
63
- end
64
-
65
- def any_response
66
- response_for(IRRELEVANT_RESPONSE_CODE, IRRELEVANT_RESPONSE_DESCRIPTION, IRRELEVANT_CONTENT_TYPE, IRRELEVANT_BODY)
67
- end
68
-
69
- end