winrm 2.0.3 → 2.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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -10
  3. data/.rubocop.yml +26 -26
  4. data/.travis.yml +11 -11
  5. data/Gemfile +3 -3
  6. data/README.md +260 -233
  7. data/Rakefile +34 -34
  8. data/Vagrantfile +6 -6
  9. data/WinrmAppveyor.psm1 +31 -31
  10. data/appveyor.yml +51 -51
  11. data/changelog.md +104 -101
  12. data/lib/winrm.rb +39 -39
  13. data/lib/winrm/connection.rb +83 -82
  14. data/lib/winrm/connection_opts.rb +91 -91
  15. data/lib/winrm/exceptions.rb +76 -76
  16. data/lib/winrm/http/response_handler.rb +96 -96
  17. data/lib/winrm/http/transport.rb +424 -424
  18. data/lib/winrm/http/transport_factory.rb +68 -68
  19. data/lib/winrm/output.rb +59 -59
  20. data/lib/winrm/psrp/create_pipeline.xml.erb +167 -167
  21. data/lib/winrm/psrp/fragment.rb +70 -70
  22. data/lib/winrm/psrp/init_runspace_pool.xml.erb +224 -224
  23. data/lib/winrm/psrp/message.rb +130 -130
  24. data/lib/winrm/psrp/message_data.rb +42 -42
  25. data/lib/winrm/psrp/message_data/base.rb +49 -49
  26. data/lib/winrm/psrp/message_data/error_record.rb +68 -68
  27. data/lib/winrm/psrp/message_data/pipeline_host_call.rb +32 -32
  28. data/lib/winrm/psrp/message_data/pipeline_output.rb +49 -49
  29. data/lib/winrm/psrp/message_data/pipeline_state.rb +40 -40
  30. data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +32 -32
  31. data/lib/winrm/psrp/message_data/runspacepool_state.rb +39 -39
  32. data/lib/winrm/psrp/message_data/session_capability.rb +36 -36
  33. data/lib/winrm/psrp/message_defragmenter.rb +62 -62
  34. data/lib/winrm/psrp/message_factory.rb +75 -75
  35. data/lib/winrm/psrp/message_fragmenter.rb +60 -60
  36. data/lib/winrm/psrp/powershell_output_decoder.rb +139 -139
  37. data/lib/winrm/psrp/receive_response_reader.rb +97 -97
  38. data/lib/winrm/psrp/session_capability.xml.erb +7 -7
  39. data/lib/winrm/psrp/uuid.rb +40 -40
  40. data/lib/winrm/shells/base.rb +180 -175
  41. data/lib/winrm/shells/cmd.rb +65 -65
  42. data/lib/winrm/shells/power_shell.rb +202 -202
  43. data/lib/winrm/shells/retryable.rb +45 -45
  44. data/lib/winrm/shells/shell_factory.rb +58 -50
  45. data/lib/winrm/version.rb +7 -7
  46. data/lib/winrm/wsmv/base.rb +59 -59
  47. data/lib/winrm/wsmv/cleanup_command.rb +61 -61
  48. data/lib/winrm/wsmv/close_shell.rb +50 -50
  49. data/lib/winrm/wsmv/command.rb +101 -101
  50. data/lib/winrm/wsmv/command_output.rb +76 -76
  51. data/lib/winrm/wsmv/command_output_decoder.rb +55 -55
  52. data/lib/winrm/wsmv/configuration.rb +46 -46
  53. data/lib/winrm/wsmv/create_pipeline.rb +66 -66
  54. data/lib/winrm/wsmv/create_shell.rb +119 -119
  55. data/lib/winrm/wsmv/header.rb +203 -203
  56. data/lib/winrm/wsmv/init_runspace_pool.rb +95 -95
  57. data/lib/winrm/wsmv/iso8601_duration.rb +60 -60
  58. data/lib/winrm/wsmv/keep_alive.rb +68 -68
  59. data/lib/winrm/wsmv/receive_response_reader.rb +126 -126
  60. data/lib/winrm/wsmv/send_data.rb +68 -68
  61. data/lib/winrm/wsmv/soap.rb +51 -51
  62. data/lib/winrm/wsmv/wql_query.rb +79 -79
  63. data/lib/winrm/wsmv/write_stdin.rb +88 -88
  64. data/tests/integration/auth_timeout_spec.rb +18 -18
  65. data/tests/integration/cmd_spec.rb +131 -110
  66. data/tests/integration/config-example.yml +16 -16
  67. data/tests/integration/issue_59_spec.rb +26 -26
  68. data/tests/integration/powershell_spec.rb +165 -165
  69. data/tests/integration/spec_helper.rb +65 -65
  70. data/tests/integration/transport_spec.rb +99 -99
  71. data/tests/integration/wql_spec.rb +16 -16
  72. data/tests/matchers.rb +60 -60
  73. data/tests/spec/configuration_spec.rb +184 -184
  74. data/tests/spec/connection_spec.rb +39 -39
  75. data/tests/spec/exception_spec.rb +50 -50
  76. data/tests/spec/http/transport_factory_spec.rb +68 -68
  77. data/tests/spec/http/transport_spec.rb +44 -44
  78. data/tests/spec/output_spec.rb +127 -127
  79. data/tests/spec/psrp/fragment_spec.rb +62 -62
  80. data/tests/spec/psrp/message_data/base_spec.rb +13 -13
  81. data/tests/spec/psrp/message_data/error_record_spec.rb +41 -41
  82. data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +25 -25
  83. data/tests/spec/psrp/message_data/pipeline_output_spec.rb +32 -32
  84. data/tests/spec/psrp/message_data/pipeline_state_spec.rb +40 -40
  85. data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +25 -25
  86. data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +16 -16
  87. data/tests/spec/psrp/message_data/session_capability_spec.rb +30 -30
  88. data/tests/spec/psrp/message_data_spec.rb +35 -35
  89. data/tests/spec/psrp/message_defragmenter_spec.rb +47 -47
  90. data/tests/spec/psrp/message_fragmenter_spec.rb +105 -105
  91. data/tests/spec/psrp/powershell_output_decoder_spec.rb +100 -100
  92. data/tests/spec/psrp/psrp_message_spec.rb +70 -70
  93. data/tests/spec/psrp/recieve_response_reader_spec.rb +172 -172
  94. data/tests/spec/psrp/uuid_spec.rb +28 -28
  95. data/tests/spec/response_handler_spec.rb +61 -61
  96. data/tests/spec/shells/base_spec.rb +202 -202
  97. data/tests/spec/shells/cmd_spec.rb +75 -75
  98. data/tests/spec/shells/powershell_spec.rb +175 -175
  99. data/tests/spec/spec_helper.rb +47 -47
  100. data/tests/spec/stubs/clixml/error_record.xml.erb +84 -84
  101. data/tests/spec/stubs/clixml/pipeline_state.xml.erb +88 -88
  102. data/tests/spec/stubs/responses/get_command_output_response.xml.erb +13 -13
  103. data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +10 -10
  104. data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +10 -10
  105. data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +12 -12
  106. data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +9 -9
  107. data/tests/spec/stubs/responses/open_shell_v1.xml +19 -19
  108. data/tests/spec/stubs/responses/open_shell_v2.xml +20 -20
  109. data/tests/spec/stubs/responses/soap_fault_v1.xml +36 -36
  110. data/tests/spec/stubs/responses/soap_fault_v2.xml +42 -42
  111. data/tests/spec/stubs/responses/wmi_error_v2.xml +41 -41
  112. data/tests/spec/wsmv/cleanup_command_spec.rb +22 -22
  113. data/tests/spec/wsmv/close_shell_spec.rb +17 -17
  114. data/tests/spec/wsmv/command_output_decoder_spec.rb +37 -37
  115. data/tests/spec/wsmv/command_output_spec.rb +45 -45
  116. data/tests/spec/wsmv/command_spec.rb +19 -19
  117. data/tests/spec/wsmv/configuration_spec.rb +17 -17
  118. data/tests/spec/wsmv/create_pipeline_spec.rb +31 -31
  119. data/tests/spec/wsmv/create_shell_spec.rb +38 -38
  120. data/tests/spec/wsmv/init_runspace_pool_spec.rb +36 -36
  121. data/tests/spec/wsmv/keep_alive_spec.rb +21 -21
  122. data/tests/spec/wsmv/receive_response_reader_spec.rb +123 -123
  123. data/tests/spec/wsmv/send_data_spec.rb +30 -30
  124. data/tests/spec/wsmv/wql_query_spec.rb +13 -13
  125. data/tests/spec/wsmv/write_stdin_spec.rb +22 -22
  126. data/winrm.gemspec +42 -42
  127. metadata +2 -2
@@ -1,16 +1,16 @@
1
- # encoding: UTF-8
2
-
3
- require 'winrm/psrp/message_data/base'
4
- require 'winrm/psrp/message_data/runspacepool_state'
5
-
6
- describe WinRM::PSRP::MessageData::RunspacepoolState do
7
- let(:raw_data) do
8
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I32 N=\"RunspaceState\">2</I32></MS></Obj>"
9
- end
10
-
11
- subject { described_class.new(raw_data) }
12
-
13
- it 'parses runspace state' do
14
- expect(subject.runspace_state).to eq(WinRM::PSRP::MessageData::RunspacepoolState::OPENED)
15
- end
16
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'winrm/psrp/message_data/base'
4
+ require 'winrm/psrp/message_data/runspacepool_state'
5
+
6
+ describe WinRM::PSRP::MessageData::RunspacepoolState do
7
+ let(:raw_data) do
8
+ "\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I32 N=\"RunspaceState\">2</I32></MS></Obj>"
9
+ end
10
+
11
+ subject { described_class.new(raw_data) }
12
+
13
+ it 'parses runspace state' do
14
+ expect(subject.runspace_state).to eq(WinRM::PSRP::MessageData::RunspacepoolState::OPENED)
15
+ end
16
+ end
@@ -1,30 +1,30 @@
1
- # encoding: UTF-8
2
-
3
- require 'winrm/psrp/message_data/base'
4
- require 'winrm/psrp/message_data/session_capability'
5
-
6
- describe WinRM::PSRP::MessageData::SessionCapability do
7
- let(:protocol_version) { '2.2' }
8
- let(:ps_version) { '2.0' }
9
- let(:serialization_version) { '1.1.0.1' }
10
- let(:raw_data) do
11
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS>"\
12
- "<Version N=\"protocolversion\">#{protocol_version}</Version>"\
13
- "<Version N=\"PSVersion\">#{ps_version}</Version>"\
14
- "<Version N=\"SerializationVersion\">#{serialization_version}</Version></MS></Obj>"
15
- end
16
-
17
- subject { described_class.new(raw_data) }
18
-
19
- it 'parses protocol version' do
20
- expect(subject.protocol_version).to eq(protocol_version)
21
- end
22
-
23
- it 'parses ps version' do
24
- expect(subject.ps_version).to eq(ps_version)
25
- end
26
-
27
- it 'parses serialization version' do
28
- expect(subject.serialization_version).to eq(serialization_version)
29
- end
30
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'winrm/psrp/message_data/base'
4
+ require 'winrm/psrp/message_data/session_capability'
5
+
6
+ describe WinRM::PSRP::MessageData::SessionCapability do
7
+ let(:protocol_version) { '2.2' }
8
+ let(:ps_version) { '2.0' }
9
+ let(:serialization_version) { '1.1.0.1' }
10
+ let(:raw_data) do
11
+ "\xEF\xBB\xBF<Obj RefId=\"0\"><MS>"\
12
+ "<Version N=\"protocolversion\">#{protocol_version}</Version>"\
13
+ "<Version N=\"PSVersion\">#{ps_version}</Version>"\
14
+ "<Version N=\"SerializationVersion\">#{serialization_version}</Version></MS></Obj>"
15
+ end
16
+
17
+ subject { described_class.new(raw_data) }
18
+
19
+ it 'parses protocol version' do
20
+ expect(subject.protocol_version).to eq(protocol_version)
21
+ end
22
+
23
+ it 'parses ps version' do
24
+ expect(subject.ps_version).to eq(ps_version)
25
+ end
26
+
27
+ it 'parses serialization version' do
28
+ expect(subject.serialization_version).to eq(serialization_version)
29
+ end
30
+ end
@@ -1,35 +1,35 @@
1
- # encoding: UTF-8
2
-
3
- require 'winrm/psrp/message'
4
- require 'winrm/psrp/message_data'
5
-
6
- describe WinRM::PSRP::MessageData do
7
- describe '#parse' do
8
- let(:raw_data) { 'raw_data' }
9
- let(:message) do
10
- WinRM::PSRP::Message.new(
11
- '00000000-0000-0000-0000-000000000000',
12
- message_type,
13
- raw_data
14
- )
15
- end
16
-
17
- subject { WinRM::PSRP::MessageData.parse(message) }
18
-
19
- context 'defined message type' do
20
- let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
21
-
22
- it 'creates correct message data type' do
23
- expect(subject).to be_a(WinRM::PSRP::MessageData::PipelineOutput)
24
- end
25
- end
26
-
27
- context 'undefined message type' do
28
- let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_input] }
29
-
30
- it 'returns nill' do
31
- expect(subject).to be nil
32
- end
33
- end
34
- end
35
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'winrm/psrp/message'
4
+ require 'winrm/psrp/message_data'
5
+
6
+ describe WinRM::PSRP::MessageData do
7
+ describe '#parse' do
8
+ let(:raw_data) { 'raw_data' }
9
+ let(:message) do
10
+ WinRM::PSRP::Message.new(
11
+ '00000000-0000-0000-0000-000000000000',
12
+ message_type,
13
+ raw_data
14
+ )
15
+ end
16
+
17
+ subject { WinRM::PSRP::MessageData.parse(message) }
18
+
19
+ context 'defined message type' do
20
+ let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
21
+
22
+ it 'creates correct message data type' do
23
+ expect(subject).to be_a(WinRM::PSRP::MessageData::PipelineOutput)
24
+ end
25
+ end
26
+
27
+ context 'undefined message type' do
28
+ let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_input] }
29
+
30
+ it 'returns nill' do
31
+ expect(subject).to be nil
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,47 +1,47 @@
1
- # encoding: UTF-8
2
-
3
- require 'winrm/psrp/message_defragmenter'
4
-
5
- describe WinRM::PSRP::MessageDefragmenter do
6
- context 'a real life fragment' do
7
- let(:bytes) do
8
- "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00I\x01"\
9
- "\x00\x00\x00\x04\x10\x04\x00Kk/=Z\xD3-E\x81v\xA0+6\xB1\xD3\x88\n\xED\x90\x9Cj\xE7PG"\
10
- "\x9F\xA2\xB2\xC99to9\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string
11
- end
12
- subject { described_class.new.defragment(Base64.encode64(bytes)) }
13
-
14
- it 'parses the data' do
15
- expect(subject.data).to eq("\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string)
16
- end
17
-
18
- it 'parses the destination' do
19
- expect(subject.destination).to eq(1)
20
- end
21
-
22
- it 'parses the message type' do
23
- expect(subject.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output])
24
- end
25
- end
26
-
27
- context 'multiple fragments' do
28
- let(:blob) do
29
- WinRM::PSRP::Message.new(
30
- 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
31
- WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
32
- 'This is a fragmented message'
33
- )
34
- end
35
- let(:fragment1) { WinRM::PSRP::Fragment.new(1, blob.bytes[0..5], 0, true, false) }
36
- let(:fragment2) { WinRM::PSRP::Fragment.new(1, blob.bytes[6..10], 1, false, false) }
37
- let(:fragment3) { WinRM::PSRP::Fragment.new(1, blob.bytes[11..-1], 2, false, true) }
38
-
39
- it 'pieces the message together' do
40
- subject.defragment(Base64.strict_encode64(fragment1.bytes.pack('C*')))
41
- subject.defragment(Base64.strict_encode64(fragment2.bytes.pack('C*')))
42
- message = subject.defragment(Base64.strict_encode64(fragment3.bytes.pack('C*')))
43
-
44
- expect(message.data[3..-1]).to eq(blob.data)
45
- end
46
- end
47
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'winrm/psrp/message_defragmenter'
4
+
5
+ describe WinRM::PSRP::MessageDefragmenter do
6
+ context 'a real life fragment' do
7
+ let(:bytes) do
8
+ "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00I\x01"\
9
+ "\x00\x00\x00\x04\x10\x04\x00Kk/=Z\xD3-E\x81v\xA0+6\xB1\xD3\x88\n\xED\x90\x9Cj\xE7PG"\
10
+ "\x9F\xA2\xB2\xC99to9\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string
11
+ end
12
+ subject { described_class.new.defragment(Base64.encode64(bytes)) }
13
+
14
+ it 'parses the data' do
15
+ expect(subject.data).to eq("\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string)
16
+ end
17
+
18
+ it 'parses the destination' do
19
+ expect(subject.destination).to eq(1)
20
+ end
21
+
22
+ it 'parses the message type' do
23
+ expect(subject.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output])
24
+ end
25
+ end
26
+
27
+ context 'multiple fragments' do
28
+ let(:blob) do
29
+ WinRM::PSRP::Message.new(
30
+ 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
31
+ WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
32
+ 'This is a fragmented message'
33
+ )
34
+ end
35
+ let(:fragment1) { WinRM::PSRP::Fragment.new(1, blob.bytes[0..5], 0, true, false) }
36
+ let(:fragment2) { WinRM::PSRP::Fragment.new(1, blob.bytes[6..10], 1, false, false) }
37
+ let(:fragment3) { WinRM::PSRP::Fragment.new(1, blob.bytes[11..-1], 2, false, true) }
38
+
39
+ it 'pieces the message together' do
40
+ subject.defragment(Base64.strict_encode64(fragment1.bytes.pack('C*')))
41
+ subject.defragment(Base64.strict_encode64(fragment2.bytes.pack('C*')))
42
+ message = subject.defragment(Base64.strict_encode64(fragment3.bytes.pack('C*')))
43
+
44
+ expect(message.data[3..-1]).to eq(blob.data)
45
+ end
46
+ end
47
+ end
@@ -1,105 +1,105 @@
1
- # encoding: UTF-8
2
-
3
- require 'winrm/psrp/message'
4
- require 'winrm/psrp/message_fragmenter'
5
-
6
- describe WinRM::PSRP::MessageFragmenter do
7
- let(:message) do
8
- WinRM::PSRP::Message.new(
9
- 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
10
- WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
11
- data
12
- )
13
- end
14
-
15
- subject do
16
- fragmenter = described_class.new(45)
17
- fragments = []
18
- fragmenter.fragment(message) do |fragment|
19
- fragments.push(fragment)
20
- end
21
- fragments
22
- end
23
-
24
- context 'one fragment' do
25
- let(:data) { 'th' }
26
-
27
- it 'returns 1 fragment' do
28
- expect(subject.length).to eq(1)
29
- end
30
-
31
- it 'has blob data equal to the message bytes' do
32
- expect(subject[0].blob.length).to eq(message.bytes.length)
33
- end
34
-
35
- it 'identifies the fragment as start and end' do
36
- expect(subject[0].start_fragment).to eq(true)
37
- expect(subject[0].end_fragment).to eq(true)
38
- end
39
-
40
- it 'assigns fragment id correctly' do
41
- expect(subject[0].fragment_id).to eq(0)
42
- end
43
- end
44
-
45
- context 'two fragments' do
46
- let(:data) { 'This is a fragmented message' }
47
-
48
- it 'splits the message' do
49
- expect(subject.length).to eq(2)
50
- end
51
-
52
- it 'has a sum of blob data equal to the message bytes' do
53
- expect(subject[0].blob.length + subject[1].blob.length).to eq(message.bytes.length)
54
- end
55
-
56
- it 'identifies the first fragment as start and not end' do
57
- expect(subject[0].start_fragment).to eq(true)
58
- expect(subject[0].end_fragment).to eq(false)
59
- end
60
-
61
- it 'identifies the first fragment as start and not end' do
62
- expect(subject[1].start_fragment).to eq(false)
63
- expect(subject[1].end_fragment).to eq(true)
64
- end
65
-
66
- it 'assigns incementing fragment ids' do
67
- expect(subject[0].fragment_id).to eq(0)
68
- expect(subject[1].fragment_id).to eq(1)
69
- end
70
- end
71
-
72
- context 'three fragments' do
73
- let(:data) { 'This is a fragmented message because framents are lovely' }
74
-
75
- it 'splits the message' do
76
- expect(subject.length).to eq(3)
77
- end
78
-
79
- it 'has a sum of blob data equal to the message bytes' do
80
- expect(subject[0].blob.length + subject[1].blob.length + subject[2].blob.length)
81
- .to eq(message.bytes.length)
82
- end
83
-
84
- it 'identifies the first fragment as start and not end' do
85
- expect(subject[0].start_fragment).to eq(true)
86
- expect(subject[0].end_fragment).to eq(false)
87
- end
88
-
89
- it 'identifies the first fragment as start and not end' do
90
- expect(subject[1].start_fragment).to eq(false)
91
- expect(subject[1].end_fragment).to eq(false)
92
- end
93
-
94
- it 'identifies the third fragment as not start and end' do
95
- expect(subject[2].start_fragment).to eq(false)
96
- expect(subject[2].end_fragment).to eq(true)
97
- end
98
-
99
- it 'assigns incementing fragment ids' do
100
- expect(subject[0].fragment_id).to eq(0)
101
- expect(subject[1].fragment_id).to eq(1)
102
- expect(subject[2].fragment_id).to eq(2)
103
- end
104
- end
105
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'winrm/psrp/message'
4
+ require 'winrm/psrp/message_fragmenter'
5
+
6
+ describe WinRM::PSRP::MessageFragmenter do
7
+ let(:message) do
8
+ WinRM::PSRP::Message.new(
9
+ 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
10
+ WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
11
+ data
12
+ )
13
+ end
14
+
15
+ subject do
16
+ fragmenter = described_class.new(45)
17
+ fragments = []
18
+ fragmenter.fragment(message) do |fragment|
19
+ fragments.push(fragment)
20
+ end
21
+ fragments
22
+ end
23
+
24
+ context 'one fragment' do
25
+ let(:data) { 'th' }
26
+
27
+ it 'returns 1 fragment' do
28
+ expect(subject.length).to eq(1)
29
+ end
30
+
31
+ it 'has blob data equal to the message bytes' do
32
+ expect(subject[0].blob.length).to eq(message.bytes.length)
33
+ end
34
+
35
+ it 'identifies the fragment as start and end' do
36
+ expect(subject[0].start_fragment).to eq(true)
37
+ expect(subject[0].end_fragment).to eq(true)
38
+ end
39
+
40
+ it 'assigns fragment id correctly' do
41
+ expect(subject[0].fragment_id).to eq(0)
42
+ end
43
+ end
44
+
45
+ context 'two fragments' do
46
+ let(:data) { 'This is a fragmented message' }
47
+
48
+ it 'splits the message' do
49
+ expect(subject.length).to eq(2)
50
+ end
51
+
52
+ it 'has a sum of blob data equal to the message bytes' do
53
+ expect(subject[0].blob.length + subject[1].blob.length).to eq(message.bytes.length)
54
+ end
55
+
56
+ it 'identifies the first fragment as start and not end' do
57
+ expect(subject[0].start_fragment).to eq(true)
58
+ expect(subject[0].end_fragment).to eq(false)
59
+ end
60
+
61
+ it 'identifies the first fragment as start and not end' do
62
+ expect(subject[1].start_fragment).to eq(false)
63
+ expect(subject[1].end_fragment).to eq(true)
64
+ end
65
+
66
+ it 'assigns incementing fragment ids' do
67
+ expect(subject[0].fragment_id).to eq(0)
68
+ expect(subject[1].fragment_id).to eq(1)
69
+ end
70
+ end
71
+
72
+ context 'three fragments' do
73
+ let(:data) { 'This is a fragmented message because framents are lovely' }
74
+
75
+ it 'splits the message' do
76
+ expect(subject.length).to eq(3)
77
+ end
78
+
79
+ it 'has a sum of blob data equal to the message bytes' do
80
+ expect(subject[0].blob.length + subject[1].blob.length + subject[2].blob.length)
81
+ .to eq(message.bytes.length)
82
+ end
83
+
84
+ it 'identifies the first fragment as start and not end' do
85
+ expect(subject[0].start_fragment).to eq(true)
86
+ expect(subject[0].end_fragment).to eq(false)
87
+ end
88
+
89
+ it 'identifies the first fragment as start and not end' do
90
+ expect(subject[1].start_fragment).to eq(false)
91
+ expect(subject[1].end_fragment).to eq(false)
92
+ end
93
+
94
+ it 'identifies the third fragment as not start and end' do
95
+ expect(subject[2].start_fragment).to eq(false)
96
+ expect(subject[2].end_fragment).to eq(true)
97
+ end
98
+
99
+ it 'assigns incementing fragment ids' do
100
+ expect(subject[0].fragment_id).to eq(0)
101
+ expect(subject[1].fragment_id).to eq(1)
102
+ expect(subject[2].fragment_id).to eq(2)
103
+ end
104
+ end
105
+ end