Skip to content

Commit

Permalink
Merge pull request #1973 from alphagov/mvp-one-generate-mermaid-code
Browse files Browse the repository at this point in the history
Mvp one generate mermaid code
  • Loading branch information
anatron authored Dec 4, 2023
2 parents 610f84b + 0ef227b commit ce056e5
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
38 changes: 38 additions & 0 deletions app/models/simple_smart_answer_edition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,26 @@ def destroy_in_attrs?(attrs)
attrs.delete("_destroy") == "1"
end

def generate_mermaid
parts = ["%%{ init: {\n'theme': 'base',\n'themeVariables': {\n " \
"'background': '#FFFFFF',\n 'primaryTextColor': '#0B0C0C',\n " \
"'lineColor': '#0b0c0c',\n 'fontSize': '23.75px' } } }%%\nflowchart TD"]
parts << "accTitle: #{title}\naccDescr: A flowchart for the #{title} smart answer\nAA[Start]:::start"
if nodes.present?
parts << "AA---Q#{nodes.first.slug.split('-')[1]}"
nodes.each do |node|
parts << if node.kind == "question"
mermaid_question(node)
elsif node.kind == "outcome"
mermaid_outcome(node)
end
end
end
parts << "classDef answer fill: #F3F2F1, stroke:#505A5F;\nclassDef outcome fill: #6FA4D2" \
"\nclassDef question fill: #B1B4B6, stroke:#505A5F;\nclassDef start fill:#00703c,color: #ffffff"
parts.join("\n")
end

private

def question(node)
Expand All @@ -99,4 +119,22 @@ def outcome(node)
body = node.body == "" ? "" : "\n#{node.body}"
"#{node.slug.titleize}\n#{node.title}#{body}"
end

def mermaid_question(node)
question_node_id = node.slug.split("-")[1]
part = ["Q#{question_node_id}[\"`Q#{question_node_id}. #{node.title}`\"]:::question"]
node.options.each.with_index(1) do |option, index|
answer_node_id = "Q#{question_node_id}A#{index}"
next_node_title, next_node_number = option.next_node.split("-")
part << "Q#{question_node_id}---#{answer_node_id}\n" \
"#{answer_node_id}([\"`A#{index}. #{option.label}`\"]):::answer\n" \
"#{answer_node_id}-->#{next_node_title[0].upcase}#{next_node_number}\n"
end
part.join("\n")
end

def mermaid_outcome(node)
outcome_node_id = node.slug.split("-")[1]
"O#{outcome_node_id}{{\"`O#{outcome_node_id}. #{node.title}`\"}}:::outcome"
end
end
1 change: 1 addition & 0 deletions app/views/editions/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@
</div><!--/.tab-content -->
</div><!--/.tabbable -->
<% content_for :page_title, "Editing #{@resource.title}" %>

53 changes: 52 additions & 1 deletion test/models/simple_smart_answer_edition_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ class SimpleSmartAnswerEditionTest < ActiveSupport::TestCase
edition.nodes.build(slug: "outcome-1", title: "The first outcome", order: 3, kind: "outcome", body: "Outcome body")
edition.nodes.build(slug: "outcome-2", title: "The second outcome", order: 4, kind: "outcome")

assert_equal "Introduction to the smart answer\n\n\nQuestion 1\nThe first question\n\nBody\n\nAnswer 1\noption one\nNext question for user: Outcome 1 (The first outcome)\n\nAnswer 2\noption two\nNext question for user: Outcome 2 (The second outcome)\n\n\n\nOutcome 1\nThe first outcome\nOutcome body\n\n\nOutcome 2\nThe second outcome\n", edition.whole_body
assert_equal "Introduction to the smart answer\n\n\nQuestion 1\nThe first question\n\nBody\n\nAnswer 1\noption one" \
"\nNext question for user: Outcome 1 (The first outcome)\n\nAnswer 2\noption two\nNext question for" \
" user: Outcome 2 (The second outcome)\n\n\n\nOutcome 1\nThe first outcome\nOutcome body\n\n\nOutcome" \
" 2\nThe second outcome\n", edition.whole_body
end

should "create nodes with nested attributes" do
Expand Down Expand Up @@ -237,5 +240,53 @@ class SimpleSmartAnswerEditionTest < ActiveSupport::TestCase
assert_equal 2, @edition.nodes.size
end
end

context "generating mermaid.js syntax" do
should "generate correct syntax from a simple smart answer with no nodes" do
edition = FactoryBot.build(:simple_smart_answer_edition, panopticon_id: @artefact.id)
edition.update(title: "Smarter than the average answer")
edition.save!

assert_equal "%%{ init: {\n'theme': 'base',\n'themeVariables': {\n 'background': '#FFFFFF',\n" \
" 'primaryTextColor': '#0B0C0C',\n 'lineColor': '#0b0c0c',\n 'fontSize': '23.75px'" \
" } } }%%\nflowchart TD\naccTitle: Smarter than the average answer\naccDescr: A flowchart for the Smarter " \
"than the average answer smart answer\nAA[Start]:::start\nclassDef answer fill: #F3F2F1, stroke:#505A5F;\nclassDef " \
"outcome fill: #6FA4D2\nclassDef question fill: #B1B4B6, stroke:#505A5F;\nclassDef start fill:#00703c,color: " \
"#ffffff", edition.generate_mermaid
end

should "generate correct syntax from a simple smart answer with one node" do
edition = FactoryBot.build(:simple_smart_answer_edition, panopticon_id: @artefact.id)
edition.update(title: "Smarter than the average answer")
edition.nodes.build(slug: "question-1", title: "You approach two locked doors. Which do you choose?", kind: "question")

edition.save!

assert_equal "%%{ init: {\n'theme': 'base',\n'themeVariables': {\n 'background': '#FFFFFF',\n" \
" 'primaryTextColor': '#0B0C0C',\n 'lineColor': '#0b0c0c',\n 'fontSize': '23.75px'" \
" } } }%%\nflowchart TD\naccTitle: Smarter than the average answer\naccDescr: A flowchart for the Smarter " \
"than the average answer smart answer\nAA[Start]:::start\nAA---Q1\nQ1[\"`Q1. You approach two locked doors. " \
"Which do you choose?`\"]:::question\nclassDef answer fill: #F3F2F1, stroke:#505A5F;\nclassDef " \
"outcome fill: #6FA4D2\nclassDef question fill: #B1B4B6, stroke:#505A5F;\nclassDef start fill:#00703c,color: " \
"#ffffff", edition.generate_mermaid
end

should "generate mermaid.js syntax from a simple smart answer with multiple nodes" do
edition = FactoryBot.build(:simple_smart_answer_edition, panopticon_id: @artefact.id)

edition.nodes.build(slug: "question-1", title: "You approach two locked doors. Which do you choose?", kind: "question", options: [{ label: "A tiger fights you", next_node: "outcome-1" }])
edition.nodes.build(slug: "outcome-1", title: "Tiger wins", kind: "outcome")
edition.save!

assert_equal "%%{ init: {\n'theme': 'base',\n'themeVariables': {\n 'background': '#FFFFFF',\n" \
" 'primaryTextColor': '#0B0C0C',\n 'lineColor': '#0b0c0c',\n 'fontSize': '23.75px'" \
" } } }%%\nflowchart TD\naccTitle: Simple smart answer\naccDescr: A flowchart for the Simple " \
"smart answer smart answer\nAA[Start]:::start\nAA---Q1\nQ1[\"`Q1. You approach two locked doors. " \
"Which do you choose?`\"]:::question\nQ1---Q1A1\nQ1A1([\"`A1. A tiger fights you`\"]):::answer\n" \
"Q1A1-->O1\n\nO1{{\"`O1. Tiger wins`\"}}:::outcome\nclassDef answer fill: #F3F2F1, stroke:#505A5F;\nclassDef " \
"outcome fill: #6FA4D2\nclassDef question fill: #B1B4B6, stroke:#505A5F;\nclassDef start fill:#00703c,color: " \
"#ffffff", edition.generate_mermaid
end
end
# rubocop:enable Rails/SaveBang
end

0 comments on commit ce056e5

Please sign in to comment.