# frozen_string_literal: true require('defmastership') RSpec.describe(DefMastership::Document) do describe '.new' do it { is_expected.not_to(be(nil)) } it { is_expected.to(have_attributes(definitions: [])) } it { is_expected.to(have_attributes(eref: {})) } it { is_expected.to(have_attributes(iref: false)) } it { is_expected.to(have_attributes(attributes: {})) } it { is_expected.to(have_attributes(variables: {})) } end describe '#parse' do subject(:document) { described_class.new } context 'with valid definitions' do let(:definition) { instance_double(DefMastership::Definition, 'definition') } before do allow(DefMastership::Definition).to(receive(:new).and_return(definition)) allow(definition).to(receive(:labels).and_return(Set.new)) allow(definition).to(receive(:<<).and_return(definition)) allow(definition).to(receive(:add_eref).and_return(definition)) allow(definition).to(receive(:add_iref).and_return(definition)) end context 'when simple definition line' do let(:input_lines) { ['[define, requirement, TOTO-0001]'] } before do allow(DefMastership::Definition).to(receive(:new).with( matchdata_including( type: 'requirement', reference: 'TOTO-0001' ) ).and_return(definition)) document.parse(input_lines) end it do expect(DefMastership::Definition).to(have_received(:new).with( matchdata_including(type: 'requirement', reference: 'TOTO-0001') )) end it { expect(document).to(have_attributes(definitions: [definition])) } end context 'when complete definition with content' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', '--', 'a', 'b', '--', 'not included' ] end before do allow(definition).to(receive(:<<).and_return(definition)) document.parse(input_lines) end it { expect(definition).to(have_received(:<<).with('a')) } it { expect(definition).to(have_received(:<<).with('b')) } end context 'when definition with one paragraph' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'one line', 'another line', '', 'not included' ] end before do allow(definition).to(receive(:<<).and_return(definition)) document.parse(input_lines) end it { expect(definition).to(have_received(:<<).with('one line')) } it { expect(definition).to(have_received(:<<).with('another line')) } end context 'when definition with one paragraph followed by a block' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'one line', 'another line', '--', 'not included', '--' ] end before { document.parse(input_lines) } it { expect(definition).not_to(have_received(:<<).with('not included')) } end context 'when block without definition' do let(:input_lines) { ['--', 'first line', '--'] } it do document.parse(input_lines) expect(document.definitions).to(eq([])) end end context 'when definition with labels' do let(:input_lines) do [ '[define, requirement, TOTO-0001, [label1, label2]]', 'one line', 'not included' ] end before do allow(definition).to(receive(:labels).and_return(Set['bla1', 'bla2'])) document.parse(input_lines) end it do expect(DefMastership::Definition).to(have_received(:new).with(matchdata_including( type: 'requirement', reference: 'TOTO-0001', labels: 'label1, label2' ))) end it { expect(document.labels).to(eq(Set['bla1', 'bla2'])) } end context 'when definition with labels without spaces' do let(:input_lines) do [ '[define,requirement,TOTO-0001,[label1,label2]]', 'one line', 'not included' ] end before do allow(definition).to(receive(:labels).and_return(Set['bla1', 'bla2'])) document.parse(input_lines) end it do expect(DefMastership::Definition).to(have_received(:new).with(matchdata_including( type: 'requirement', reference: 'TOTO-0001', labels: 'label1,label2' ))) end it { expect(document.labels).to(eq(Set['bla1', 'bla2'])) } end context 'when setup external links' do let(:input_lines) do [ ':eref-implements-prefix: Participate to:', ':eref-implements-url: ./other_document.html', 'one line', 'not included' ] end before { document.parse(input_lines) } it { expect(document.eref[:implements]).to(eq(prefix: 'Participate to:', url: './other_document.html')) } end context 'when setup external links without url' do let(:input_lines) do [ ':eref-implements-prefix: Participate to:', 'one line', 'not included' ] end it do document.parse(input_lines) expect(document.eref[:implements]) .to(eq(prefix: 'Participate to:')) end end context 'when define external links' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'one line', 'defs:eref[implements, [SYSTEM-0012, SYSTEM-0014]]' ] end before do allow(definition).to(receive(:add_eref).with(:implements, 'SYSTEM-0012, SYSTEM-0014') .and_return(definition)) document.parse(input_lines) end it { expect(definition).to(have_received(:add_eref).with(:implements, 'SYSTEM-0012, SYSTEM-0014')) } end context 'when define internal links' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'defs:iref[toto] defs:iref[tutu]', 'defs:iref[pouet]' ] end before do allow(definition).to(receive(:add_iref)) document.parse(input_lines) end it { expect(definition).to(have_received(:add_iref).with('toto')) } it { expect(definition).to(have_received(:add_iref).with('tutu')) } it { expect(definition).to(have_received(:add_iref).with('pouet')) } it { expect(document.iref).to(eq(true)) } end context 'when configure attributes' do let(:input_lines) do [ ':attr-myattribute-prefix: My attribute:', ':attr-myotherone-prefix: My other attribute:' ] end before { document.parse(input_lines) } it { expect(document.attributes).to(eq(myattribute: 'My attribute:', myotherone: 'My other attribute:')) } end context 'when setup attributes value' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'defs:attribute[myattribute, My value]' ] end before do allow(definition).to(receive(:set_attribute).with(:myattribute, 'My value')) document.parse(input_lines) end it { expect(definition).to(have_received(:set_attribute).with(:myattribute, 'My value')) } end context 'when putting comments' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', '// defs:iref[toto] defs:iref[tutu]' ] end it do document.parse(input_lines) expect(document.iref).to(eq(false)) end end context 'when definition in wrong literal block' do let(:input_lines) do [ '1234', '[define, requirement, TOTO-0001]' ] end before do allow(DefMastership::Definition).to(receive(:new).with(matchdata_including( type: 'requirement', reference: 'TOTO-0001' )).and_return(definition)) document.parse(input_lines) end it do expect(DefMastership::Definition).to(have_received(:new).with(matchdata_including( type: 'requirement', reference: 'TOTO-0001' ))) end end end context 'when variables replacement' do let(:definition) { instance_double(DefMastership::Definition, 'definition') } before do allow(DefMastership::Definition).to(receive(:new).and_return(definition)) allow(definition).to(receive(:labels).and_return(Set.new)) allow(definition).to(receive(:<<).and_return(definition)) document.parse(input_lines) end context 'when defined variable' do let(:input_lines) do [ ':variable: one value', '[define, requirement, TOTO-0001]', 'bef {variable} aft' ] end it { expect(document).to(have_attributes(variables: { variable: 'one value' })) } it { expect(definition).to(have_received(:<<).with('bef one value aft')) } end context 'when not defined variable' do let(:input_lines) do [ '[define, requirement, TOTO-0001]', 'bef {variable} aft' ] end it { expect(definition).to(have_received(:<<).with('bef {variable} aft')) } end context 'when multiple defined variables' do let(:input_lines) do [ ':variable: one', ':variable2: two', '[define, requirement, TOTO-0001]', 'bef {variable} {variable2} aft' ] end it { expect(definition).to(have_received(:<<).with('bef one two aft')) } end end context 'with invalid definitions' do context 'when definition in literal block' do let(:input_lines) do [ '....', '[define, requirement, TOTO-0001]', '....' ] end before do allow(DefMastership::Definition).to(receive(:new) .and_raise('not a valide definition')) end it do document.parse(input_lines) expect(document).to(have_attributes(definitions: [])) end end context 'when definition in comment block' do let(:input_lines) do [ '////', '[define, requirement, TOTO-0001]', '////' ] end before do allow(DefMastership::Definition).to(receive(:new) .and_raise('not a valide definition')) end it do document.parse(input_lines) expect(document).to(have_attributes(definitions: [])) end end end end end