require 'spec_helper' describe Gitlab::Ci::Trace::SectionParser do def lines_with_pos(text) pos = 0 StringIO.new(text).each_line do |line| yield line, pos pos += line.bytesize + 1 # newline end end def build_lines(text) to_enum(:lines_with_pos, text) end def section(name, start, duration, text) end_ = start + duration "section_start:#{start.to_i}:#{name}\r\033[0K#{text}section_end:#{end_.to_i}:#{name}\r\033[0K" end let(:lines) { build_lines('') } subject { described_class.new(lines) } describe '#sections' do before do subject.parse! end context 'empty trace' do let(:lines) { build_lines('') } it { expect(subject.sections).to be_empty } end context 'with a sectionless trace' do let(:lines) { build_lines("line 1\nline 2\n") } it { expect(subject.sections).to be_empty } end context 'with trace markers' do let(:start_time) { Time.new(2017, 10, 5).utc } let(:section_b_duration) { 1.second } let(:section_a) { section('a', start_time, 0, 'a line') } let(:section_b) { section('b', start_time, section_b_duration, "another line\n") } let(:lines) { build_lines(section_a + section_b) } it { expect(subject.sections.size).to eq(2) } it { expect(subject.sections[1][:name]).to eq('b') } it { expect(subject.sections[1][:date_start]).to eq(start_time) } it { expect(subject.sections[1][:date_end]).to eq(start_time + section_b_duration) } end end describe '#parse!' do context 'multiple "section_" but no complete markers' do let(:lines) { build_lines('section_section_section_') } it 'must find 3 possible section start but no complete sections' do expect(subject).to receive(:find_next_marker).exactly(3).times.and_call_original subject.parse! expect(subject.sections).to be_empty end end context 'trace with UTF-8 chars' do let(:line) { 'GitLab ❤️ 狸 (tanukis)\n' } let(:trace) { section('test_section', Time.new(2017, 10, 5).utc, 3.seconds, line) } let(:lines) { build_lines(trace) } it 'must handle correctly byte positioning' do expect(subject).to receive(:find_next_marker).exactly(2).times.and_call_original subject.parse! sections = subject.sections expect(sections.size).to eq(1) s = sections[0] len = s[:byte_end] - s[:byte_start] expect(trace.byteslice(s[:byte_start], len)).to eq(line) end end end end