defmodule MfmParserTest do use ExUnit.Case doctest MfmParser alias MfmParser.Node describe "to_html" do test "it handles text" do input_tree = [%Node.Text{props: %{text: "chocolatine"}}] expected = "chocolatine" assert MfmParser.to_html(input_tree) == expected end test "it handles newlines" do input_tree = [%Node.Newline{props: %{text: "\n"}}] expected = "\n" assert MfmParser.to_html(input_tree) == expected end test "it handles flip" do input_tree = [ %Node.MFM.Flip{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}] } ] input_tree_v = [ %Node.MFM.Flip{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}], props: %{v: true} } ] input_tree_h_v = [ %Node.MFM.Flip{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}], props: %{v: true, h: true} } ] expected = ~s[Misskey expands the world of the Fediverse] expected_v = ~s[Misskey expands the world of the Fediverse] expected_h_v = ~s[Misskey expands the world of the Fediverse] assert MfmParser.to_html(input_tree) == expected assert MfmParser.to_html(input_tree_v) == expected_v assert MfmParser.to_html(input_tree_h_v) == expected_h_v end test "it handles font" do input_tree = [ %Node.MFM.Font{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}], props: %{font: "fantasy"} } ] expected = ~s[Misskey expands the world of the Fediverse] assert MfmParser.to_html(input_tree) == expected end test "it handles x" do input_tree = [ %Node.MFM.X{ children: [%Node.Text{props: %{text: "🍮"}}], props: %{size: "400%"} } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles blur" do input_tree = [ %Node.MFM.Blur{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}] } ] expected = ~s[Misskey expands the world of the Fediverse] assert MfmParser.to_html(input_tree) == expected end test "it handles jelly" do input_tree = [ %Node.MFM.Jelly{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles tada" do input_tree = [ %Node.MFM.Tada{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles jump" do input_tree = [ %Node.MFM.Jump{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles bounce" do input_tree = [ %Node.MFM.Bounce{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles spin" do input_tree_spin_reverse = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spin", direction: "reverse", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spinx_reverse = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinX", direction: "reverse", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spiny_reverse = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinY", direction: "reverse", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spin_alternate = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spin", direction: "alternate", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spinx_alternate = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinX", direction: "alternate", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spiny_alternate = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinY", direction: "alternate", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spin_normal = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spin", direction: "normal", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spinx_normal = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinX", direction: "normal", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] input_tree_spiny_normal = [ %Node.MFM.Spin{ props: %{keyframes_name: "mfm-spinY", direction: "normal", speed: "1.5s"}, children: [%Node.Text{props: %{text: "🍮"}}] } ] expected_tree_spin_reverse = ~s[🍮] expected_tree_spinx_reverse = ~s[🍮] expected_tree_spiny_reverse = ~s[🍮] expected_tree_spin_alternate = ~s[🍮] expected_tree_spinx_alternate = ~s[🍮] expected_tree_spiny_alternate = ~s[🍮] expected_tree_spin_normal = ~s[🍮] expected_tree_spinx_normal = ~s[🍮] expected_tree_spiny_normal = ~s[🍮] assert MfmParser.to_html(input_tree_spin_reverse) == expected_tree_spin_reverse assert MfmParser.to_html(input_tree_spinx_reverse) == expected_tree_spinx_reverse assert MfmParser.to_html(input_tree_spiny_reverse) == expected_tree_spiny_reverse assert MfmParser.to_html(input_tree_spin_alternate) == expected_tree_spin_alternate assert MfmParser.to_html(input_tree_spinx_alternate) == expected_tree_spinx_alternate assert MfmParser.to_html(input_tree_spiny_alternate) == expected_tree_spiny_alternate assert MfmParser.to_html(input_tree_spin_normal) == expected_tree_spin_normal assert MfmParser.to_html(input_tree_spinx_normal) == expected_tree_spinx_normal assert MfmParser.to_html(input_tree_spiny_normal) == expected_tree_spiny_normal end test "it handles shake" do input_tree = [ %Node.MFM.Shake{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles twitch" do input_tree = [ %Node.MFM.Twitch{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles rainbow" do input_tree = [ %Node.MFM.Rainbow{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles sparkle" do # TODO: This is not how Misskey does it and should be changed to make it work like Misskey. input_tree = [ %Node.MFM.Sparkle{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles rotate" do input_tree = [ %Node.MFM.Rotate{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles unsuported formats" do input_tree = [ %Node.MFM.Undefined{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles multpile nodes on the same level" do input_tree = [ %Node.MFM.Rotate{ children: [%Node.Text{props: %{text: "🍮"}}] }, %Node.Text{props: %{text: "pain au chocolat"}}, %Node.MFM.Font{ children: [%Node.Text{props: %{text: "Misskey expands the world of the Fediverse"}}], props: %{font: "fantasy"} } ] expected = ~s[🍮pain au chocolatMisskey expands the world of the Fediverse] assert MfmParser.to_html(input_tree) == expected end test "it handles nesting" do input_tree = [ %Node.MFM.Rotate{ children: [ %Node.MFM.Font{ children: [%Node.Text{props: %{text: "🍮"}}], props: %{font: "fantasy"} } ] } ] expected = ~s[🍮] assert MfmParser.to_html(input_tree) == expected end test "it shouldn't have duplicate styles" do input_tree = [ %Node.MFM.Sparkle{ children: [%Node.Text{props: %{text: "🍮"}}] }, %Node.MFM.Sparkle{ children: [%Node.Text{props: %{text: "🍮"}}] } ] expected = ~s[🍮🍮] assert MfmParser.to_html(input_tree) == expected end test "it handles complex nesting of nodes" do input_tree = [ %MfmParser.Node.Text{props: %{text: "It's not "}}, %MfmParser.Node.MFM.Twitch{ children: [%MfmParser.Node.Text{props: %{text: "chocolatine"}}], props: %{speed: "0.2s"} }, %MfmParser.Node.Newline{props: %{text: "\n"}}, %MfmParser.Node.Text{props: %{text: "it's "}}, %MfmParser.Node.MFM.X{ children: [ %MfmParser.Node.MFM.Spin{ children: [%MfmParser.Node.Text{props: %{text: "pain"}}], props: %{direction: "normal", keyframes_name: "mfm-spin", speed: "1s"} }, %MfmParser.Node.Text{props: %{text: " "}}, %MfmParser.Node.MFM.Rainbow{ children: [%MfmParser.Node.Text{props: %{text: "au"}}], props: %{speed: "2s"} }, %MfmParser.Node.Text{props: %{text: " "}}, %MfmParser.Node.MFM.Jump{ children: [%MfmParser.Node.Text{props: %{text: "chocolat"}}], props: %{speed: "0.5s"} } ], props: %{size: "600%"} } ] expected = "It's not chocolatine\nit's pain au chocolat" assert MfmParser.to_html(input_tree) == expected end test "it should be able to go from mfm-text input to html output" do input = "It's not $[twitch.speed=0.2s chocolatine]\nit's $[x4 $[spin.speed=1s pain] $[rainbow.speed=2s au] $[jump.speed=0.5s chocolat]]" expected = "It's not chocolatine\nit's pain au chocolat" assert MfmParser.to_html(input) == expected end # I would like to have options # * as much as possible in the span vs only a class and everything in style # * with or without style # end end