-
Notifications
You must be signed in to change notification settings - Fork 0
fix: treat code mark as exclusive in ADF inline formatting #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package api | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestMarkdownToADF_CodeInsideBold(t *testing.T) { | ||
| adf := MarkdownToADF("**Bold with `code` inside**") | ||
|
|
||
| if len(adf.Content) != 1 { | ||
| t.Fatalf("expected 1 block, got %d", len(adf.Content)) | ||
| } | ||
|
|
||
| para := adf.Content[0] | ||
| if para.Type != "paragraph" { | ||
| t.Fatalf("expected paragraph, got %s", para.Type) | ||
| } | ||
|
|
||
| if len(para.Content) != 3 { | ||
| b, _ := json.MarshalIndent(adf, "", " ") | ||
| t.Fatalf("expected 3 inline nodes, got %d:\n%s", len(para.Content), b) | ||
| } | ||
|
|
||
| // "Bold with " should have strong mark | ||
| if para.Content[0].Text != "Bold with " { | ||
| t.Errorf("expected 'Bold with ', got %q", para.Content[0].Text) | ||
| } | ||
| if len(para.Content[0].Marks) != 1 || para.Content[0].Marks[0].Type != "strong" { | ||
| t.Errorf("expected [strong] marks, got %v", para.Content[0].Marks) | ||
| } | ||
|
|
||
| // "code" should have ONLY code mark (not strong+code) | ||
| if para.Content[1].Text != "code" { | ||
| t.Errorf("expected 'code', got %q", para.Content[1].Text) | ||
| } | ||
| if len(para.Content[1].Marks) != 1 || para.Content[1].Marks[0].Type != "code" { | ||
| t.Errorf("expected [code] marks only, got %v", para.Content[1].Marks) | ||
| } | ||
|
|
||
| // " inside" should have strong mark | ||
| if para.Content[2].Text != " inside" { | ||
| t.Errorf("expected ' inside', got %q", para.Content[2].Text) | ||
| } | ||
| if len(para.Content[2].Marks) != 1 || para.Content[2].Marks[0].Type != "strong" { | ||
| t.Errorf("expected [strong] marks, got %v", para.Content[2].Marks) | ||
| } | ||
| } | ||
|
|
||
| func TestMarkdownToADF_CodeInsideItalic(t *testing.T) { | ||
| adf := MarkdownToADF("*italic `code` here*") | ||
|
|
||
| para := adf.Content[0] | ||
| for _, c := range para.Content { | ||
| if hasCodeMark(c) { | ||
| if len(c.Marks) != 1 { | ||
| t.Errorf("code node should have only code mark, got %v", c.Marks) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestMarkdownToADF_CodeInsideStrikethrough(t *testing.T) { | ||
| adf := MarkdownToADF("~~deleted `code` here~~") | ||
|
|
||
| para := adf.Content[0] | ||
| for _, c := range para.Content { | ||
| if hasCodeMark(c) { | ||
| if len(c.Marks) != 1 { | ||
| t.Errorf("code node should have only code mark, got %v", c.Marks) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+63
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the italic test, this test for strikethrough can be strengthened. Explicitly checking that the text segments around the func TestMarkdownToADF_CodeInsideStrikethrough(t *testing.T) {
adf := MarkdownToADF("~~deleted `code` here~~")
if len(adf.Content) != 1 {
t.Fatalf("expected 1 block, got %d", len(adf.Content))
}
para := adf.Content[0]
if para.Type != "paragraph" {
t.Fatalf("expected paragraph, got %s", para.Type)
}
if len(para.Content) != 3 {
b, _ := json.MarshalIndent(adf, "", " ")
t.Fatalf("expected 3 inline nodes, got %d:\n%s", len(para.Content), b)
}
// "deleted " should have strike mark
if para.Content[0].Text != "deleted " {
t.Errorf("expected 'deleted ', got %q", para.Content[0].Text)
}
if len(para.Content[0].Marks) != 1 || para.Content[0].Marks[0].Type != "strike" {
t.Errorf("expected [strike] marks, got %v", para.Content[0].Marks)
}
// "code" should have ONLY code mark
if para.Content[1].Text != "code" {
t.Errorf("expected 'code', got %q", para.Content[1].Text)
}
if len(para.Content[1].Marks) != 1 || para.Content[1].Marks[0].Type != "code" {
t.Errorf("expected [code] marks only, got %v", para.Content[1].Marks)
}
// " here" should have strike mark
if para.Content[2].Text != " here" {
t.Errorf("expected ' here', got %q", para.Content[2].Text)
}
if len(para.Content[2].Marks) != 1 || para.Content[2].Marks[0].Type != "strike" {
t.Errorf("expected [strike] marks, got %v", para.Content[2].Marks)
}
} |
||
|
|
||
| func TestMarkdownToADF_BoldWithCodeAndCodeBlock(t *testing.T) { | ||
| // This was the exact combination that caused INVALID_INPUT from Jira | ||
| md := "**Migration: Falsche `s_action` korrigieren**\n\n```sql\nSELECT 1\n```" | ||
| adf := MarkdownToADF(md) | ||
|
|
||
| if len(adf.Content) != 2 { | ||
| b, _ := json.MarshalIndent(adf, "", " ") | ||
| t.Fatalf("expected 2 blocks (paragraph + codeBlock), got %d:\n%s", len(adf.Content), b) | ||
| } | ||
|
|
||
| // Verify no code node has additional marks | ||
| para := adf.Content[0] | ||
| for _, c := range para.Content { | ||
| if hasCodeMark(c) && len(c.Marks) > 1 { | ||
| t.Errorf("code node should have only code mark, got %v", c.Marks) | ||
| } | ||
| } | ||
|
|
||
| // Verify code block is present | ||
| if adf.Content[1].Type != "codeBlock" { | ||
| t.Errorf("expected codeBlock, got %s", adf.Content[1].Type) | ||
| } | ||
| } | ||
|
Comment on lines
+76
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test covers the specific case that triggered the bug, which is excellent. To make it even more solid, I suggest adding assertions to verify that the non-code parts of the bolded string also have the func TestMarkdownToADF_BoldWithCodeAndCodeBlock(t *testing.T) {
// This was the exact combination that caused INVALID_INPUT from Jira
md := "**Migration: Falsche `s_action` korrigieren**\n\n```sql\nSELECT 1\n```"
adf := MarkdownToADF(md)
if len(adf.Content) != 2 {
b, _ := json.MarshalIndent(adf, "", " ")
t.Fatalf("expected 2 blocks (paragraph + codeBlock), got %d:\n%s", len(adf.Content), b)
}
// Verify paragraph content
para := adf.Content[0]
if para.Type != "paragraph" {
t.Fatalf("expected paragraph, got %s", para.Type)
}
if len(para.Content) != 3 {
b, _ := json.MarshalIndent(para, "", " ")
t.Fatalf("expected 3 inline nodes in paragraph, got %d:\n%s", len(para.Content), b)
}
// "Migration: Falsche " should have strong mark
if para.Content[0].Text != "Migration: Falsche " {
t.Errorf("expected 'Migration: Falsche ', got %q", para.Content[0].Text)
}
if len(para.Content[0].Marks) != 1 || para.Content[0].Marks[0].Type != "strong" {
t.Errorf("expected [strong] marks, got %v", para.Content[0].Marks)
}
// "s_action" should have ONLY code mark
if para.Content[1].Text != "s_action" {
t.Errorf("expected 's_action', got %q", para.Content[1].Text)
}
if len(para.Content[1].Marks) != 1 || para.Content[1].Marks[0].Type != "code" {
t.Errorf("expected [code] marks only, got %v", para.Content[1].Marks)
}
// " korrigieren" should have strong mark
if para.Content[2].Text != " korrigieren" {
t.Errorf("expected ' korrigieren', got %q", para.Content[2].Text)
}
if len(para.Content[2].Marks) != 1 || para.Content[2].Marks[0].Type != "strong" {
t.Errorf("expected [strong] marks, got %v", para.Content[2].Marks)
}
// Verify code block is present
if adf.Content[1].Type != "codeBlock" {
t.Errorf("expected codeBlock, got %s", adf.Content[1].Type)
}
} |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test correctly verifies that
codemarks are exclusive. To make it more robust, I suggest expanding it to also assert that the non-code parts of the string correctly receive theemmark. This would provide a more complete validation, similar toTestMarkdownToADF_CodeInsideBold.