Project

General

Profile

« Previous | Next » 

Revision 7d4f91f0

Added by Oleksandr Ivanov 1 day ago

Impl: Decision record id and type are added to the overview table (#170)

View differences:

lib/almirah/doc_types/decision.rb
require_relative 'base_document'
class Decision < BaseDocument # rubocop:disable Style/Documentation
attr_accessor :path
attr_accessor :path, :sequence_number, :record_type
def initialize(file_path)
super()
@path = file_path
@id = File.basename(file_path, File.extname(file_path)).downcase
@title = extract_title(file_path) || @id
stem = File.basename(file_path, File.extname(file_path))
assign_id_parts(stem)
@title = extract_title(file_path) || stem
end
def to_console
......
private
def assign_id_parts(stem)
match = stem.match(/\A([A-Za-z]+)-(\d+)/)
if match
@id = "#{match[1]}-#{match[2]}".downcase
@record_type = match[1].upcase
@sequence_number = match[2]
else
@id = stem.downcase
@record_type = nil
@sequence_number = nil
end
end
def extract_title(file_path)
File.foreach(file_path) do |line|
if (match = /^\#\s+(.+)$/.match(line))
lib/almirah/doc_types/decisions_overview.rb
html_rows.append "<table class=\"controlled\">\n"
html_rows.append "\t<thead>\n"
html_rows.append "\t\t<th>ID</th>\n"
html_rows.append "\t\t<th>#</th>\n"
html_rows.append "\t\t<th>Type</th>\n"
html_rows.append "\t\t<th>Title</th>\n"
html_rows.append "</thead>\n"
sorted_items = @project.project_data.decisions.sort_by(&:id)
sorted_items.each do |doc|
s = "\t<tr>\n"
s += "\t\t<td class=\"item_id\" style='width: 20%;'>#{doc.id}</td>\n"
s += "\t\t<td class=\"item_id\">\n"
label = doc.sequence_number || doc.id
anchor_attrs = %(name="#{doc.id}" id="#{doc.id}" href="##{doc.id}" title="Decision Record ID")
s += "\t\t\t<a #{anchor_attrs}><b>#{label}</b></a>"
s += "\t\t</td>\n"
s += "\t\t<td class=\"item_type\">#{doc.record_type}</td>\n"
s += "\t\t<td class=\"item_text\" style='padding: 5px;'>#{doc.title}</td>\n"
s += "</tr>\n"
html_rows.append s
lib/almirah/templates/css/main.css
width: 3%;
text-align: center;
}
table.controlled td.item_type {
width: 5%;
text-align: center;
font-weight: normal;
}
table.controlled td.item_text{
text-align: left;
}
spec/e2e/decisions_spec.rb
it 'lists all parsed decision records on the overview page' do
doc = Nokogiri::HTML(File.read(expand_path('myproject/build/decisions/overview.html')))
ids = doc.xpath('//td[@class="item_id"]').map { |c| c.text.strip }
sequence_numbers = doc.xpath('//td[@class="item_id"]').map { |c| c.text.strip }
anchor_ids = doc.xpath('//td[@class="item_id"]//a').map { |a| a['id'] }
types = doc.xpath('//td[@class="item_type"]').map { |c| c.text.strip }
titles = doc.xpath('//td[@class="item_text"]').map { |c| c.text.strip }
expect(ids).to contain_exactly('adr-001-foo', 'adr-002-bar')
expect(sequence_numbers).to contain_exactly('001', '002')
expect(anchor_ids).to contain_exactly('adr-001', 'adr-002')
expect(types).to contain_exactly('ADR', 'ADR')
expect(titles).to contain_exactly('ADR-001: First Decision', 'ADR-002: Second Decision')
end
......
specifications:
input: []
YML
write_file('myproject/specifications/req/req.md', "# Requirements\n\n[REQ-001] x\n")
write_file('myproject/decisions/adr-001-titleless.md', "body without heading\n")
run_command_and_stop('almirah please myproject')
end
it 'falls back to the filename-derived id for the title' do
it 'derives the id from the letters-digits prefix and falls back to the full stem for the title' do
doc = Nokogiri::HTML(File.read(expand_path('myproject/build/decisions/overview.html')))
sequence_numbers = doc.xpath('//td[@class="item_id"]').map { |c| c.text.strip }
anchor_ids = doc.xpath('//td[@class="item_id"]//a').map { |a| a['id'] }
types = doc.xpath('//td[@class="item_type"]').map { |c| c.text.strip }
titles = doc.xpath('//td[@class="item_text"]').map { |c| c.text.strip }
expect(sequence_numbers).to eq(['001'])
expect(anchor_ids).to eq(['adr-001'])
expect(types).to eq(['ADR'])
expect(titles).to eq(['adr-001-titleless'])
end
end
context 'when a decision record filename has no descriptive suffix' do
before do
write_file('myproject/project.yml', <<~YML)
specifications:
input: []
YML
write_file('myproject/decisions/ise-1892.md', <<~MD)
# ISE-1892: A redmine-style record
body
MD
run_command_and_stop('almirah please myproject')
end
it 'uses the full letters-digits stem as the id and shows the digits in the # column' do
doc = Nokogiri::HTML(File.read(expand_path('myproject/build/decisions/overview.html')))
sequence_numbers = doc.xpath('//td[@class="item_id"]').map { |c| c.text.strip }
anchor_ids = doc.xpath('//td[@class="item_id"]//a').map { |a| a['id'] }
types = doc.xpath('//td[@class="item_type"]').map { |c| c.text.strip }
titles = doc.xpath('//td[@class="item_text"]').map { |c| c.text.strip }
expect(sequence_numbers).to eq(['1892'])
expect(anchor_ids).to eq(['ise-1892'])
expect(types).to eq(['ISE'])
expect(titles).to eq(['ISE-1892: A redmine-style record'])
end
end
context 'when a decision record filename does not match the convention' do
before do
write_file('myproject/project.yml', <<~YML)
specifications:
input: []
YML
write_file('myproject/decisions/meeting-notes.md', <<~MD)
# Meeting notes
body
MD
run_command_and_stop('almirah please myproject')
end
it 'falls back to the full filename stem as the id and as the # column label, with empty Type' do
doc = Nokogiri::HTML(File.read(expand_path('myproject/build/decisions/overview.html')))
sequence_numbers = doc.xpath('//td[@class="item_id"]').map { |c| c.text.strip }
anchor_ids = doc.xpath('//td[@class="item_id"]//a').map { |a| a['id'] }
types = doc.xpath('//td[@class="item_type"]').map { |c| c.text.strip }
expect(sequence_numbers).to eq(['meeting-notes'])
expect(anchor_ids).to eq(['meeting-notes'])
expect(types).to eq([''])
end
end
context 'when the project has no decision records' do
before do
write_file('myproject/project.yml', <<~YML)

Also available in: Unified diff