Skip to content

Commit a5d96e2

Browse files
committed
Fix remaining issues with mdx_expression_flow test suite.
1 parent 2ef311e commit a5d96e2

File tree

6 files changed

+112
-60
lines changed

6 files changed

+112
-60
lines changed

apps/markdown/src/markdown_message.erl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ FormattedMessage = markdown_message:format(Message),
9494
-spec format(Message) -> FormattedMessage when
9595
Message :: t(),
9696
FormattedMessage :: unicode:unicode_binary().
97-
format(#markdown_message{place = {some, #markdown_place{inner = #markdown_unist_point{line = Line, column = Column}}}, reason = Reason, rule_id = RuleId, source = Source}) ->
97+
format(#markdown_message{
98+
place = {some, #markdown_place{inner = #markdown_unist_point{line = Line, column = Column}}},
99+
reason = Reason,
100+
rule_id = RuleId,
101+
source = Source
102+
}) ->
98103
iolist_to_binary(io_lib:format("~w:~w: ~ts (~ts:~ts)", [Line, Column, Reason, Source, RuleId]));
99104
format(#markdown_message{place = none, reason = Reason, rule_id = RuleId, source = Source}) ->
100105
iolist_to_binary(io_lib:format("~ts (~ts:~ts)", [Reason, Source, RuleId])).

apps/markdown_test/src/markdown_test_utils_swc.erl

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,12 @@ parse_expression_impl(Value, _Kind) ->
125125
ok ->
126126
% No issues found, check if balanced
127127
case is_balanced_with_comments(Value) of
128-
true -> markdown_mdx_signal:ok();
129-
false -> markdown_mdx_signal:eof(<<"Unexpected eof">>, <<"mdx">>, <<"mdx">>)
128+
true ->
129+
markdown_mdx_signal:ok();
130+
false ->
131+
markdown_mdx_signal:eof(
132+
<<"Unexpected eof">>, <<"mdx">>, <<"mdx">>
133+
)
130134
end;
131135
{error, Offset} ->
132136
% Found content after a complete expression
@@ -182,7 +186,8 @@ check_line_comment_eof_impl(<<"/*", Rest/binary>>, Offset, false) ->
182186
{ok, NewRest, NewOffset} ->
183187
check_line_comment_eof_impl(NewRest, NewOffset, false);
184188
eof ->
185-
ok % Multiline comment EOF is handled by is_balanced
189+
% Multiline comment EOF is handled by is_balanced
190+
ok
186191
end;
187192
% Skip other characters
188193
check_line_comment_eof_impl(<<_:8, Rest/binary>>, Offset, InLineComment) ->
@@ -211,9 +216,21 @@ check_for_statement(Value) ->
211216
Trimmed = string:trim(Value, leading),
212217
LeadingWSSize = byte_size(Value) - byte_size(Trimmed),
213218
% Check for statement keywords
214-
Statements = [<<"var ">>, <<"let ">>, <<"const ">>, <<"if ">>, <<"for ">>,
215-
<<"while ">>, <<"do ">>, <<"switch ">>, <<"return ">>,
216-
<<"throw ">>, <<"break">>, <<"continue">>, <<"debugger">>],
219+
Statements = [
220+
<<"var ">>,
221+
<<"let ">>,
222+
<<"const ">>,
223+
<<"if ">>,
224+
<<"for ">>,
225+
<<"while ">>,
226+
<<"do ">>,
227+
<<"switch ">>,
228+
<<"return ">>,
229+
<<"throw ">>,
230+
<<"break">>,
231+
<<"continue">>,
232+
<<"debugger">>
233+
],
217234
case lists:any(fun(Keyword) -> starts_with_keyword(Trimmed, Keyword) end, Statements) of
218235
true ->
219236
{error, LeadingWSSize};
@@ -397,10 +414,13 @@ check_if_separate_identifiers([First | Rest]) ->
397414
case is_simple_identifier(FirstTrimmed) of
398415
true ->
399416
% Check if any remaining lines are also identifiers
400-
lists:any(fun(Line) ->
401-
Trimmed = string:trim(Line, both),
402-
is_simple_identifier(Trimmed)
403-
end, Rest);
417+
lists:any(
418+
fun(Line) ->
419+
Trimmed = string:trim(Line, both),
420+
is_simple_identifier(Trimmed)
421+
end,
422+
Rest
423+
);
404424
false ->
405425
false
406426
end;
@@ -423,9 +443,10 @@ is_simple_identifier_impl(<<>>) ->
423443
true;
424444
is_simple_identifier_impl(<<C:8, Rest/binary>>) when
425445
(C >= $a andalso C =< $z) orelse
426-
(C >= $A andalso C =< $Z) orelse
427-
(C >= $0 andalso C =< $9) orelse
428-
C =:= $_ ->
446+
(C >= $A andalso C =< $Z) orelse
447+
(C >= $0 andalso C =< $9) orelse
448+
C =:= $_
449+
->
429450
is_simple_identifier_impl(Rest);
430451
is_simple_identifier_impl(_) ->
431452
false.
@@ -456,10 +477,14 @@ find_identifier_then_brace(<<"{", Rest/binary>>, Offset, true, true) ->
456477
{found, Offset}
457478
end;
458479
% Track non-whitespace characters (potential identifier)
459-
find_identifier_then_brace(<<C:8, Rest/binary>>, Offset, _SeenNonWS, SeenWS) when C =/= $\s andalso C =/= $\t andalso C =/= $\n andalso C =/= $\r ->
480+
find_identifier_then_brace(<<C:8, Rest/binary>>, Offset, _SeenNonWS, SeenWS) when
481+
C =/= $\s andalso C =/= $\t andalso C =/= $\n andalso C =/= $\r
482+
->
460483
find_identifier_then_brace(Rest, Offset + 1, true, SeenWS);
461484
% Track whitespace after identifier
462-
find_identifier_then_brace(<<C:8, Rest/binary>>, Offset, true, _SeenWS) when C =:= $\s orelse C =:= $\t orelse C =:= $\n orelse C =:= $\r ->
485+
find_identifier_then_brace(<<C:8, Rest/binary>>, Offset, true, _SeenWS) when
486+
C =:= $\s orelse C =:= $\t orelse C =:= $\n orelse C =:= $\r
487+
->
463488
find_identifier_then_brace(Rest, Offset + 1, true, true);
464489
% Skip leading whitespace
465490
find_identifier_then_brace(<<_:8, Rest/binary>>, Offset, false, false) ->
@@ -499,17 +524,19 @@ validate_attribute_expression(Value) ->
499524

500525
% Special handling for empty or malformed expressions
501526
% Check various conditions that indicate an empty spread
502-
IsEmptySpread = TrimmedLen =:= 0 orelse
503-
ValueLen =:= 0 orelse
504-
(ValueLen =:= 1 andalso (Value =:= <<" ">> orelse Value =:= <<0>>)),
527+
IsEmptySpread =
528+
TrimmedLen =:= 0 orelse
529+
ValueLen =:= 0 orelse
530+
(ValueLen =:= 1 andalso (Value =:= <<" ">> orelse Value =:= <<0>>)),
505531

506532
% Special check for malformed assignment-like patterns in JSX attributes
507533
% If the trimmed value is exactly "b=c" (3 chars) or similar simple assignments,
508534
% it might be part of a malformed larger expression like {b=c}={}
509535
% In such cases, we should still return "not a spread" error
510-
IsMalformedContext = TrimmedLen =:= 3 andalso
511-
binary:match(Trimmed, <<"=">>) =/= nomatch andalso
512-
binary:match(Value, <<"}">>) =/= nomatch,
536+
IsMalformedContext =
537+
TrimmedLen =:= 3 andalso
538+
binary:match(Trimmed, <<"=">>) =/= nomatch andalso
539+
binary:match(Value, <<"}">>) =/= nomatch,
513540

514541
case {IsEmptySpread, IsMalformedContext} of
515542
{true, _} ->
@@ -540,17 +567,22 @@ case_not_empty_spread(Trimmed, Value, ValueLen) ->
540567
case AllWhitespace of
541568
true ->
542569
% Treat as empty
543-
{error, <<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>, 4};
570+
{error,
571+
<<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>,
572+
4};
544573
false ->
545574
% Not a spread - determine if it's a simple assignment
546575
IsCleanAssignment = is_clean_assignment(Trimmed, Value),
547576
case IsCleanAssignment of
548577
true ->
549578
% Simple assignment like "b=c"
550-
{error, <<"Could not parse expression with swc: assignment property is invalid syntax">>, 7};
579+
{error, <<"Could not parse expression with swc: assignment property is invalid syntax">>,
580+
7};
551581
false ->
552582
% Not a spread - offset at start
553-
{error, <<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>, 0}
583+
{error,
584+
<<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>,
585+
0}
554586
end
555587
end
556588
end.
@@ -559,9 +591,10 @@ case_not_empty_spread(Trimmed, Value, ValueLen) ->
559591
case_not_empty_spread_old(Trimmed, Value, ValueLen) ->
560592
% Check if effectively empty (empty, whitespace, or very short)
561593
TrimmedLen = byte_size(Trimmed),
562-
IsEffectivelyEmpty = TrimmedLen =:= 0 orelse
563-
(ValueLen < 2 andalso TrimmedLen =:= 0) orelse
564-
(ValueLen =:= 0),
594+
IsEffectivelyEmpty =
595+
TrimmedLen =:= 0 orelse
596+
(ValueLen < 2 andalso TrimmedLen =:= 0) orelse
597+
(ValueLen =:= 0),
565598

566599
case IsEffectivelyEmpty of
567600
true ->
@@ -578,17 +611,23 @@ case_not_empty_spread_old(Trimmed, Value, ValueLen) ->
578611
case AllWhitespace of
579612
true ->
580613
% Treat as empty
581-
{error, <<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>, 4};
614+
{error,
615+
<<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>,
616+
4};
582617
false ->
583618
% Not a spread - determine if it's a simple assignment
584619
IsCleanAssignment = is_clean_assignment(Trimmed, Value),
585620
case IsCleanAssignment of
586621
true ->
587622
% Simple assignment like "b=c"
588-
{error, <<"Could not parse expression with swc: assignment property is invalid syntax">>, 7};
623+
{error,
624+
<<"Could not parse expression with swc: assignment property is invalid syntax">>,
625+
7};
589626
false ->
590627
% Not a spread - offset at start
591-
{error, <<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>, 0}
628+
{error,
629+
<<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>,
630+
0}
592631
end
593632
end
594633
end
@@ -614,10 +653,11 @@ is_clean_assignment(Trimmed, Original) ->
614653
% 1. Has exactly one = sign
615654
% 2. No braces in either trimmed or original
616655
% 3. No closing brace } in original (would indicate malformed syntax like {b=c}={})
617-
HasBraces = binary:match(Trimmed, <<"{">>) =/= nomatch orelse
618-
binary:match(Trimmed, <<"}">>) =/= nomatch orelse
619-
binary:match(Original, <<"{">>) =/= nomatch orelse
620-
binary:match(Original, <<"}">>) =/= nomatch,
656+
HasBraces =
657+
binary:match(Trimmed, <<"{">>) =/= nomatch orelse
658+
binary:match(Trimmed, <<"}">>) =/= nomatch orelse
659+
binary:match(Original, <<"{">>) =/= nomatch orelse
660+
binary:match(Original, <<"}">>) =/= nomatch,
621661

622662
case HasBraces of
623663
true ->
@@ -642,7 +682,7 @@ is_simple_assignment(Value) ->
642682
% Check if this is a simple assignment pattern: identifier = value
643683
% Must have = but no braces
644684
case {binary:match(Value, <<"=">>), binary:match(Value, <<"{">>), binary:match(Value, <<"}">>)} of
645-
{{_,_}, nomatch, nomatch} ->
685+
{{_, _}, nomatch, nomatch} ->
646686
% Has equals but no braces - it's a simple assignment
647687
true;
648688
_ ->
@@ -672,11 +712,16 @@ validate_spread(Rest, ValueLen) ->
672712
ok;
673713
{error, Type} when Type =:= assignment ->
674714
% For assignment errors, offset at end
675-
{error, <<"Could not parse expression with swc: assignment property is invalid syntax">>, ValueLen + 7};
715+
{error, <<"Could not parse expression with swc: assignment property is invalid syntax">>,
716+
ValueLen + 7};
676717
{error, Type} when Type =:= extra_content ->
677-
{error, <<"Unexpected extra content in spread (such as `{...x,y}`): only a single spread is supported (such as `{...x}`)">>, 0};
718+
{error,
719+
<<"Unexpected extra content in spread (such as `{...x,y}`): only a single spread is supported (such as `{...x}`)">>,
720+
0};
678721
{error, Type} when Type =:= comment_only ->
679-
{error, <<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>, 0}
722+
{error,
723+
<<"Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`)">>,
724+
0}
680725
end
681726
end.
682727

@@ -766,9 +811,12 @@ is_balanced_with_comments(Value) ->
766811
InComment :: boolean() | multiline | line.
767812
is_balanced_with_comments_impl(<<>>, BraceCount, BracketCount, ParenCount, InString, InComment) ->
768813
% All brackets must be balanced (count = 0) and we must not be in a string or comment
769-
BraceCount =:= 0 andalso BracketCount =:= 0 andalso ParenCount =:= 0 andalso InString =:= false andalso InComment =:= false;
814+
BraceCount =:= 0 andalso BracketCount =:= 0 andalso ParenCount =:= 0 andalso InString =:= false andalso
815+
InComment =:= false;
770816
% Handle escape sequences in strings
771-
is_balanced_with_comments_impl(<<"\\", _:8, Rest/binary>>, BraceCount, BracketCount, ParenCount, InString, InComment) when InString =/= false ->
817+
is_balanced_with_comments_impl(
818+
<<"\\", _:8, Rest/binary>>, BraceCount, BracketCount, ParenCount, InString, InComment
819+
) when InString =/= false ->
772820
is_balanced_with_comments_impl(Rest, BraceCount, BracketCount, ParenCount, InString, InComment);
773821
% Start of multiline comment (not in string)
774822
is_balanced_with_comments_impl(<<"/*", Rest/binary>>, BraceCount, BracketCount, ParenCount, false, false) ->

apps/markdown_test/test/markdown_mdx_expression_flow_SUITE.erl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%%% % DO NOT EDIT: this file was generated by 'just codegen'
2-
%%% % @generated SignedSource<<3cd9121fb521b69d9861e210f5c25c0b>>
2+
%%% % @generated SignedSource<<b90f4cd70df13414a5b7b34b6ee26c66>>
33
%%%-----------------------------------------------------------------------------
44
%%% %CopyrightBegin%
55
%%%
@@ -297,7 +297,7 @@ test_mdx_expression_flow_case_10(_Config) ->
297297
?assertMatch(
298298
{ok, <<"<p>a</p>\n<ul>\n<li>b</li>\n</ul>"/utf8>>},
299299
markdown:to_html_with_options(<<"a\n\n* b"/utf8>>, ?mdx),
300-
"should support lists after non-expressions (wooorm/erlang-markdown#11)"
300+
"should support lists after non-expressions (wooorm/markdown-rs#11)"
301301
),
302302
ok.
303303

@@ -428,7 +428,7 @@ test_mdx_expression_flow_case_19(_Config) ->
428428
Config :: ct_suite:ct_config().
429429
test_mdx_expression_flow_case_20(_Config) ->
430430
?assertMatch(
431-
{ok, <<"1:9: Could not parse expression with swc: Unexpected content after expression (mdx:swc)"/utf8>>},
431+
{ok, <<"1:8: Could not parse expression with swc: Unexpected content after expression (mdx:swc)"/utf8>>},
432432
markdown:to_html_with_options(<<"{b { c }"/utf8>>, ?swc),
433433
"should crash if no closing brace is found (2)"
434434
),
@@ -746,8 +746,7 @@ test_mdx_expression_flow_case_35(_Config) ->
746746
Config :: ct_suite:ct_config().
747747
test_mdx_expression_flow_case_36(_Config) ->
748748
?assertMatch(
749-
{ok,
750-
<<"1:5: Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`) (mdx:swc)"/utf8>>},
749+
{ok, <<"1:12: Could not parse expression with swc: assignment property is invalid syntax (mdx:swc)"/utf8>>},
751750
markdown:to_html_with_options(<<"<a {b=c}={} d>"/utf8>>, ?swc),
752751
"should crash on an incorrect spread that looks like an assignment"
753752
),
@@ -780,7 +779,7 @@ test_mdx_expression_flow_case_39(_Config) ->
780779
%% Note: `erlang-markdown` has no `allowEmpty`.
781780
?assertMatch(
782781
{ok,
783-
<<"1:9: Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`) (mdx:swc)"/utf8>>},
782+
<<"1:5: Unexpected prop in spread (such as `{x}`): only a spread is supported (such as `{...x}`) (mdx:swc)"/utf8>>},
784783
markdown:to_html_with_options(<<"<a {} />"/utf8>>, ?swc),
785784
"should crash on an empty spread"
786785
),

apps/markdown_test/test/markdown_mdx_expression_text_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%%% % DO NOT EDIT: this file was generated by 'just codegen'
2-
%%% % @generated SignedSource<<7a6978bd33c83c59b02246ba0cac29e1>>
2+
%%% % @generated SignedSource<<6d6bd09ae41d15ddb3b5faa47d272ba4>>
33
%%%-----------------------------------------------------------------------------
44
%%% %CopyrightBegin%
55
%%%

0 commit comments

Comments
 (0)