winrm 2.3.0 → 2.3.1

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/lib/winrm/http/transport.rb +1 -1
  3. data/lib/winrm/psrp/message.rb +128 -128
  4. data/lib/winrm/shells/power_shell.rb +0 -1
  5. data/lib/winrm/version.rb +1 -1
  6. metadata +12 -85
  7. data/.gitignore +0 -10
  8. data/.rubocop.yml +0 -38
  9. data/.travis.yml +0 -10
  10. data/Gemfile +0 -2
  11. data/Rakefile +0 -33
  12. data/Vagrantfile +0 -6
  13. data/WinrmAppveyor.psm1 +0 -32
  14. data/appveyor.yml +0 -50
  15. data/changelog.md +0 -133
  16. data/preamble +0 -17
  17. data/tests/integration/auth_timeout_spec.rb +0 -17
  18. data/tests/integration/cmd_spec.rb +0 -130
  19. data/tests/integration/config-example.yml +0 -16
  20. data/tests/integration/issue_59_spec.rb +0 -25
  21. data/tests/integration/powershell_spec.rb +0 -164
  22. data/tests/integration/spec_helper.rb +0 -62
  23. data/tests/integration/transport_spec.rb +0 -98
  24. data/tests/integration/wql_spec.rb +0 -33
  25. data/tests/matchers.rb +0 -59
  26. data/tests/spec/configuration_spec.rb +0 -183
  27. data/tests/spec/connection_spec.rb +0 -37
  28. data/tests/spec/exception_spec.rb +0 -49
  29. data/tests/spec/http/transport_factory_spec.rb +0 -66
  30. data/tests/spec/http/transport_spec.rb +0 -43
  31. data/tests/spec/output_spec.rb +0 -128
  32. data/tests/spec/psrp/fragment_spec.rb +0 -60
  33. data/tests/spec/psrp/message_data/base_spec.rb +0 -11
  34. data/tests/spec/psrp/message_data/error_record_spec.rb +0 -39
  35. data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +0 -23
  36. data/tests/spec/psrp/message_data/pipeline_output_spec.rb +0 -30
  37. data/tests/spec/psrp/message_data/pipeline_state_spec.rb +0 -38
  38. data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +0 -23
  39. data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +0 -14
  40. data/tests/spec/psrp/message_data/session_capability_spec.rb +0 -28
  41. data/tests/spec/psrp/message_data_spec.rb +0 -33
  42. data/tests/spec/psrp/message_defragmenter_spec.rb +0 -45
  43. data/tests/spec/psrp/message_fragmenter_spec.rb +0 -103
  44. data/tests/spec/psrp/powershell_output_decoder_spec.rb +0 -98
  45. data/tests/spec/psrp/psrp_message_spec.rb +0 -73
  46. data/tests/spec/psrp/recieve_response_reader_spec.rb +0 -170
  47. data/tests/spec/psrp/uuid_spec.rb +0 -28
  48. data/tests/spec/response_handler_spec.rb +0 -69
  49. data/tests/spec/shells/base_spec.rb +0 -227
  50. data/tests/spec/shells/cmd_spec.rb +0 -75
  51. data/tests/spec/shells/powershell_spec.rb +0 -221
  52. data/tests/spec/spec_helper.rb +0 -46
  53. data/tests/spec/stubs/clixml/error_record.xml.erb +0 -84
  54. data/tests/spec/stubs/clixml/pipeline_state.xml.erb +0 -88
  55. data/tests/spec/stubs/responses/get_command_output_response.xml.erb +0 -13
  56. data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +0 -10
  57. data/tests/spec/stubs/responses/get_omi_command_output_response.xml.erb +0 -23
  58. data/tests/spec/stubs/responses/get_omi_command_output_response_not_done.xml.erb +0 -24
  59. data/tests/spec/stubs/responses/get_omi_config_response.xml +0 -45
  60. data/tests/spec/stubs/responses/get_omi_powershell_keepalive_response.xml.erb +0 -33
  61. data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +0 -10
  62. data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +0 -12
  63. data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +0 -9
  64. data/tests/spec/stubs/responses/open_shell_omi.xml +0 -43
  65. data/tests/spec/stubs/responses/open_shell_v1.xml +0 -19
  66. data/tests/spec/stubs/responses/open_shell_v2.xml +0 -20
  67. data/tests/spec/stubs/responses/soap_fault_omi.xml +0 -31
  68. data/tests/spec/stubs/responses/soap_fault_v1.xml +0 -36
  69. data/tests/spec/stubs/responses/soap_fault_v2.xml +0 -42
  70. data/tests/spec/stubs/responses/wmi_error_v2.xml +0 -41
  71. data/tests/spec/wsmv/cleanup_command_spec.rb +0 -20
  72. data/tests/spec/wsmv/close_shell_spec.rb +0 -15
  73. data/tests/spec/wsmv/command_output_decoder_spec.rb +0 -35
  74. data/tests/spec/wsmv/command_output_spec.rb +0 -43
  75. data/tests/spec/wsmv/command_spec.rb +0 -17
  76. data/tests/spec/wsmv/configuration_spec.rb +0 -15
  77. data/tests/spec/wsmv/create_pipeline_spec.rb +0 -30
  78. data/tests/spec/wsmv/create_shell_spec.rb +0 -39
  79. data/tests/spec/wsmv/init_runspace_pool_spec.rb +0 -38
  80. data/tests/spec/wsmv/keep_alive_spec.rb +0 -21
  81. data/tests/spec/wsmv/receive_response_reader_spec.rb +0 -124
  82. data/tests/spec/wsmv/send_data_spec.rb +0 -30
  83. data/tests/spec/wsmv/wql_query_spec.rb +0 -11
  84. data/tests/spec/wsmv/write_stdin_spec.rb +0 -20
  85. data/winrm.gemspec +0 -46
@@ -1,60 +0,0 @@
1
- require 'winrm/psrp/fragment'
2
-
3
- describe WinRM::PSRP::Fragment do
4
- let(:id) { 1 }
5
- let(:message) { 'blah blah blah' }
6
-
7
- context 'called with just id and blob' do
8
- subject { described_class.new(id, message.bytes) }
9
-
10
- it 'sets the message id to 1' do
11
- expect(subject.bytes[0..7]).to eq([0, 0, 0, 0, 0, 0, 0, id])
12
- end
13
- it 'sets the fragment id to 0' do
14
- expect(subject.bytes[8..15]).to eq([0, 0, 0, 0, 0, 0, 0, 0])
15
- end
16
- it 'sets the last 2 bits of the end/start fragment' do
17
- expect(subject.bytes[16]).to eq(3)
18
- end
19
- it 'sets message blob length to 3640' do
20
- expect(subject.bytes[17..20]).to eq([0, 0, 0, message.bytes.length])
21
- end
22
- it 'sets message blob' do
23
- expect(subject.bytes[21..-1]).to eq(message.bytes)
24
- end
25
- end
26
-
27
- context 'specifying a fragment id' do
28
- let(:fragment_id) { 1 }
29
-
30
- subject { described_class.new(id, message.bytes, fragment_id) }
31
-
32
- it 'sets the fragment id' do
33
- expect(subject.bytes[8..15]).to eq([0, 0, 0, 0, 0, 0, 0, fragment_id])
34
- end
35
- end
36
-
37
- context 'middle fragment' do
38
- subject { described_class.new(id, message.bytes, 1, false, false) }
39
-
40
- it 'sets the last 2 bits of the end/start fragment to 0' do
41
- expect(subject.bytes[16]).to eq(0)
42
- end
43
- end
44
-
45
- context 'end fragment' do
46
- subject { described_class.new(id, message.bytes, 1, true, false) }
47
-
48
- it 'sets the end fragment bit' do
49
- expect(subject.bytes[16]).to eq(1)
50
- end
51
- end
52
-
53
- context 'start fragment' do
54
- subject { described_class.new(id, message.bytes, 1, false, true) }
55
-
56
- it 'sets the start fragment bit' do
57
- expect(subject.bytes[16]).to eq(2)
58
- end
59
- end
60
- end
@@ -1,11 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
-
3
- describe WinRM::PSRP::MessageData::Base do
4
- let(:raw_data) { 'raw_data' }
5
-
6
- subject { WinRM::PSRP::MessageData::Base.new(raw_data) }
7
-
8
- it 'holds raw message data' do
9
- expect(subject.raw).to eq(raw_data)
10
- end
11
- end
@@ -1,39 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/error_record'
3
-
4
- describe WinRM::PSRP::MessageData::ErrorRecord do
5
- let(:test_data_xml_template) do
6
- ERB.new(stubbed_clixml('error_record.xml.erb'))
7
- end
8
- let(:error_message) { 'an error' }
9
- let(:script_root) { 'script_root' }
10
- let(:category_message) { 'category message' }
11
- let(:stack_trace) { 'stack trace' }
12
- let(:error_id) { 'Microsoft.PowerShell.Commands.WriteErrorException' }
13
- let(:raw_data) { test_data_xml_template.result(binding) }
14
- subject { described_class.new(raw_data) }
15
-
16
- it 'returns the exception' do
17
- expect(subject.exception[:message]).to eq(error_message)
18
- end
19
-
20
- it 'returns the FullyQualifiedErrorId' do
21
- expect(subject.fully_qualified_error_id).to eq(error_id)
22
- end
23
-
24
- it 'returns the invocation info' do
25
- expect(subject.invocation_info[:line]).to eq("write-error '#{error_message}'")
26
- end
27
-
28
- it 'converts camel case properties to underscore' do
29
- expect(subject.invocation_info[:ps_script_root]).to eq(script_root)
30
- end
31
-
32
- it 'returns the error category message' do
33
- expect(subject.error_category_message).to eq(category_message)
34
- end
35
-
36
- it 'returns the script stack trace' do
37
- expect(subject.error_details_script_stack_trace).to eq(stack_trace)
38
- end
39
- end
@@ -1,23 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/pipeline_host_call'
3
-
4
- describe WinRM::PSRP::MessageData::PipelineHostCall do
5
- let(:raw_data) do
6
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I64 N=\"ci\">-100</I64><Obj N=\"mi\" RefId=\"1\">"\
7
- '<TN RefId="0"><T>System.Management.Automation.Remoting.RemoteHostMethodId</T>'\
8
- '<T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN>'\
9
- '<ToString>WriteLine3</ToString><I32>17</I32></Obj><Obj N="mp" RefId="2">'\
10
- '<TN RefId="1"><T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST>'\
11
- '<I32>7</I32><I32>0</I32><S>hello</S></LST></Obj></MS></Obj>'
12
- end
13
-
14
- subject { described_class.new(raw_data) }
15
-
16
- it 'parses method identifier' do
17
- expect(subject.method_identifier).to eq('WriteLine3')
18
- end
19
-
20
- it 'parses method parameters' do
21
- expect(subject.method_parameters[:s]).to eq('hello')
22
- end
23
- end
@@ -1,30 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/pipeline_output'
3
-
4
- describe WinRM::PSRP::MessageData::PipelineOutput do
5
- subject { described_class.new(raw_data) }
6
-
7
- context 'receiving output with BOM and no new line' do
8
- let(:raw_data) { "\xEF\xBB\xBF<obj><S>some data</S></obj>" }
9
-
10
- it 'output removes BOM and adds newline' do
11
- expect(subject.output).to eq("some data\r\n")
12
- end
13
- end
14
-
15
- context 'receiving output with encoded new line' do
16
- let(:raw_data) { '<obj><S>some data_x000D__x000A_</S></obj>' }
17
-
18
- it 'decodes without double newline' do
19
- expect(subject.output).to eq("some data\r\n")
20
- end
21
- end
22
-
23
- context 'receiving output with new line in middle' do
24
- let(:raw_data) { '<obj><S>some_x000D__x000A_data</S></obj>' }
25
-
26
- it 'decodes and replaces newline' do
27
- expect(subject.output).to eq("some\r\ndata\r\n")
28
- end
29
- end
30
- end
@@ -1,38 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/pipeline_state'
3
-
4
- describe WinRM::PSRP::MessageData::PipelineState do
5
- let(:test_data_xml_template) do
6
- ERB.new(stubbed_clixml('pipeline_state.xml.erb'))
7
- end
8
- let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::FAILED }
9
- let(:error_message) { 'an error occured' }
10
- let(:category_message) { 'category message' }
11
- let(:error_id) { 'an error occured' }
12
- let(:raw_data) { test_data_xml_template.result(binding) }
13
- subject { described_class.new(raw_data) }
14
-
15
- it 'returns the state' do
16
- expect(subject.pipeline_state).to eq(pipeline_state)
17
- end
18
-
19
- it 'returns the exception' do
20
- expect(subject.exception_as_error_record.exception[:message]).to eq(error_message)
21
- end
22
-
23
- it 'returns the FullyQualifiedErrorId' do
24
- expect(subject.exception_as_error_record.fully_qualified_error_id).to eq(error_id)
25
- end
26
-
27
- it 'returns the error category message' do
28
- expect(subject.exception_as_error_record.error_category_message).to eq(category_message)
29
- end
30
-
31
- context 'state is not failed' do
32
- let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::COMPLETED }
33
-
34
- it 'has a nil exception' do
35
- expect(subject.exception_as_error_record).to be(nil)
36
- end
37
- end
38
- end
@@ -1,23 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/runspacepool_host_call'
3
-
4
- describe WinRM::PSRP::MessageData::RunspacepoolHostCall do
5
- let(:raw_data) do
6
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I64 N=\"ci\">-100</I64><Obj N=\"mi\" RefId=\"1\">"\
7
- '<TN RefId="0"><T>System.Management.Automation.Remoting.RemoteHostMethodId</T>'\
8
- '<T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN>'\
9
- '<ToString>WriteLine3</ToString><I32>17</I32></Obj><Obj N="mp" RefId="2">'\
10
- '<TN RefId="1"><T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST>'\
11
- '<I32>7</I32><I32>0</I32><S>hello</S></LST></Obj></MS></Obj>'
12
- end
13
-
14
- subject { described_class.new(raw_data) }
15
-
16
- it 'parses method identifier' do
17
- expect(subject.method_identifier).to eq('WriteLine3')
18
- end
19
-
20
- it 'parses method parameters' do
21
- expect(subject.method_parameters[:s]).to eq('hello')
22
- end
23
- end
@@ -1,14 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/runspacepool_state'
3
-
4
- describe WinRM::PSRP::MessageData::RunspacepoolState do
5
- let(:raw_data) do
6
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I32 N=\"RunspaceState\">2</I32></MS></Obj>"
7
- end
8
-
9
- subject { described_class.new(raw_data) }
10
-
11
- it 'parses runspace state' do
12
- expect(subject.runspace_state).to eq(WinRM::PSRP::MessageData::RunspacepoolState::OPENED)
13
- end
14
- end
@@ -1,28 +0,0 @@
1
- require 'winrm/psrp/message_data/base'
2
- require 'winrm/psrp/message_data/session_capability'
3
-
4
- describe WinRM::PSRP::MessageData::SessionCapability do
5
- let(:protocol_version) { '2.2' }
6
- let(:ps_version) { '2.0' }
7
- let(:serialization_version) { '1.1.0.1' }
8
- let(:raw_data) do
9
- "\xEF\xBB\xBF<Obj RefId=\"0\"><MS>"\
10
- "<Version N=\"protocolversion\">#{protocol_version}</Version>"\
11
- "<Version N=\"PSVersion\">#{ps_version}</Version>"\
12
- "<Version N=\"SerializationVersion\">#{serialization_version}</Version></MS></Obj>"
13
- end
14
-
15
- subject { described_class.new(raw_data) }
16
-
17
- it 'parses protocol version' do
18
- expect(subject.protocol_version).to eq(protocol_version)
19
- end
20
-
21
- it 'parses ps version' do
22
- expect(subject.ps_version).to eq(ps_version)
23
- end
24
-
25
- it 'parses serialization version' do
26
- expect(subject.serialization_version).to eq(serialization_version)
27
- end
28
- end
@@ -1,33 +0,0 @@
1
- require 'winrm/psrp/message'
2
- require 'winrm/psrp/message_data'
3
-
4
- describe WinRM::PSRP::MessageData do
5
- describe '#parse' do
6
- let(:raw_data) { 'raw_data' }
7
- let(:message) do
8
- WinRM::PSRP::Message.new(
9
- '00000000-0000-0000-0000-000000000000',
10
- message_type,
11
- raw_data
12
- )
13
- end
14
-
15
- subject { WinRM::PSRP::MessageData.parse(message) }
16
-
17
- context 'defined message type' do
18
- let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
19
-
20
- it 'creates correct message data type' do
21
- expect(subject).to be_a(WinRM::PSRP::MessageData::PipelineOutput)
22
- end
23
- end
24
-
25
- context 'undefined message type' do
26
- let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_input] }
27
-
28
- it 'returns nill' do
29
- expect(subject).to be nil
30
- end
31
- end
32
- end
33
- end
@@ -1,45 +0,0 @@
1
- require 'winrm/psrp/message_defragmenter'
2
-
3
- describe WinRM::PSRP::MessageDefragmenter do
4
- context 'a real life fragment' do
5
- let(:bytes) do
6
- "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00I\x01"\
7
- "\x00\x00\x00\x04\x10\x04\x00Kk/=Z\xD3-E\x81v\xA0+6\xB1\xD3\x88\n\xED\x90\x9Cj\xE7PG"\
8
- "\x9F\xA2\xB2\xC99to9\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string
9
- end
10
- subject { described_class.new.defragment(Base64.encode64(bytes)) }
11
-
12
- it 'parses the data' do
13
- expect(subject.data).to eq("\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string)
14
- end
15
-
16
- it 'parses the destination' do
17
- expect(subject.destination).to eq(1)
18
- end
19
-
20
- it 'parses the message type' do
21
- expect(subject.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output])
22
- end
23
- end
24
-
25
- context 'multiple fragments' do
26
- let(:blob) do
27
- WinRM::PSRP::Message.new(
28
- 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
29
- WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
30
- 'This is a fragmented message'
31
- )
32
- end
33
- let(:fragment1) { WinRM::PSRP::Fragment.new(1, blob.bytes[0..5], 0, true, false) }
34
- let(:fragment2) { WinRM::PSRP::Fragment.new(1, blob.bytes[6..10], 1, false, false) }
35
- let(:fragment3) { WinRM::PSRP::Fragment.new(1, blob.bytes[11..-1], 2, false, true) }
36
-
37
- it 'pieces the message together' do
38
- subject.defragment(Base64.strict_encode64(fragment1.bytes.pack('C*')))
39
- subject.defragment(Base64.strict_encode64(fragment2.bytes.pack('C*')))
40
- message = subject.defragment(Base64.strict_encode64(fragment3.bytes.pack('C*')))
41
-
42
- expect(message.data[3..-1]).to eq(blob.data)
43
- end
44
- end
45
- end
@@ -1,103 +0,0 @@
1
- require 'winrm/psrp/message'
2
- require 'winrm/psrp/message_fragmenter'
3
-
4
- describe WinRM::PSRP::MessageFragmenter do
5
- let(:message) do
6
- WinRM::PSRP::Message.new(
7
- 'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
8
- WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
9
- data
10
- )
11
- end
12
-
13
- subject do
14
- fragmenter = described_class.new(45)
15
- fragments = []
16
- fragmenter.fragment(message) do |fragment|
17
- fragments.push(fragment)
18
- end
19
- fragments
20
- end
21
-
22
- context 'one fragment' do
23
- let(:data) { 'th' }
24
-
25
- it 'returns 1 fragment' do
26
- expect(subject.length).to eq(1)
27
- end
28
-
29
- it 'has blob data equal to the message bytes' do
30
- expect(subject[0].blob.length).to eq(message.bytes.length)
31
- end
32
-
33
- it 'identifies the fragment as start and end' do
34
- expect(subject[0].start_fragment).to eq(true)
35
- expect(subject[0].end_fragment).to eq(true)
36
- end
37
-
38
- it 'assigns fragment id correctly' do
39
- expect(subject[0].fragment_id).to eq(0)
40
- end
41
- end
42
-
43
- context 'two fragments' do
44
- let(:data) { 'This is a fragmented message' }
45
-
46
- it 'splits the message' do
47
- expect(subject.length).to eq(2)
48
- end
49
-
50
- it 'has a sum of blob data equal to the message bytes' do
51
- expect(subject[0].blob.length + subject[1].blob.length).to eq(message.bytes.length)
52
- end
53
-
54
- it 'identifies the first fragment as start and not end' do
55
- expect(subject[0].start_fragment).to eq(true)
56
- expect(subject[0].end_fragment).to eq(false)
57
- end
58
-
59
- it 'identifies the first fragment as start and not end' do
60
- expect(subject[1].start_fragment).to eq(false)
61
- expect(subject[1].end_fragment).to eq(true)
62
- end
63
-
64
- it 'assigns incementing fragment ids' do
65
- expect(subject[0].fragment_id).to eq(0)
66
- expect(subject[1].fragment_id).to eq(1)
67
- end
68
- end
69
-
70
- context 'three fragments' do
71
- let(:data) { 'This is a fragmented message because framents are lovely' }
72
-
73
- it 'splits the message' do
74
- expect(subject.length).to eq(3)
75
- end
76
-
77
- it 'has a sum of blob data equal to the message bytes' do
78
- expect(subject[0].blob.length + subject[1].blob.length + subject[2].blob.length)
79
- .to eq(message.bytes.length)
80
- end
81
-
82
- it 'identifies the first fragment as start and not end' do
83
- expect(subject[0].start_fragment).to eq(true)
84
- expect(subject[0].end_fragment).to eq(false)
85
- end
86
-
87
- it 'identifies the first fragment as start and not end' do
88
- expect(subject[1].start_fragment).to eq(false)
89
- expect(subject[1].end_fragment).to eq(false)
90
- end
91
-
92
- it 'identifies the third fragment as not start and end' do
93
- expect(subject[2].start_fragment).to eq(false)
94
- expect(subject[2].end_fragment).to eq(true)
95
- end
96
-
97
- it 'assigns incementing fragment ids' do
98
- expect(subject[0].fragment_id).to eq(0)
99
- expect(subject[1].fragment_id).to eq(1)
100
- expect(subject[2].fragment_id).to eq(2)
101
- end
102
- end
103
- end