use super::preprocess;
#[test]
fn static_regex_literals_compile() {
let _ = preprocess("{{ Version }}");
let _ = preprocess("{{ replace Version \"v\" \"\" }}");
let _ = preprocess("{{ Version | replace \"v\" \"\" }}");
let _ = preprocess("{{ in (list \"a\" \"b\") \"a\" }}");
let _ = preprocess("{{ Now.Format \"2006\" }}");
let _ = preprocess("{% if eq .Os \"linux\" %}x{% end %}");
let _ = preprocess("{{ map \"k1\" \"v1\" }}");
}
#[test]
fn test_preprocess_positional_replace() {
let input = "{{ replace Version \"v\" \"\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ replace(s=Version, old=\"v\", new=\"\") }}");
}
#[test]
fn test_preprocess_positional_replace_piped() {
let input = "{{ Version | replace \"v\" \"\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Version | replace(from=\"v\", to=\"\") }}");
}
#[test]
fn test_preprocess_positional_split() {
let input = "{{ split Version \".\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ split(s=Version, sep=\".\") }}");
}
#[test]
fn test_preprocess_positional_contains() {
let input = "{{ contains Version \"rc\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ contains(s=Version, substr=\"rc\") }}");
}
#[test]
fn test_preprocess_positional_piped_split() {
let input = "{{ Version | split \".\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Version | split(sep=\".\") }}");
}
#[test]
fn test_preprocess_positional_piped_contains() {
let input = "{{ Version | contains \"rc\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Version | contains(substr=\"rc\") }}");
}
#[test]
fn test_preprocess_named_args_unchanged() {
let input = "{{ replace(s=Version, old=\"v\", new=\"\") }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_named_filter_unchanged() {
let input = "{{ Version | replace(from=\"v\", to=\"\") }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_control_block_rewritten() {
let input = "{% if contains Version \"rc\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if contains(s=Version, substr=\"rc\") %}yes{% endif %}"
);
}
#[test]
fn test_preprocess_control_block_non_positional_unchanged() {
let input = "{% if Version %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_positional_replace_with_dot_var() {
let input = "{{ replace .Tag \"v\" \"\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ replace(s=Tag, old=\"v\", new=\"\") }}");
}
#[test]
fn test_positional_piped_with_dot_var() {
let input = "{{ .Tag | replace \"v\" \"\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Tag | replace(from=\"v\", to=\"\") }}");
}
#[test]
fn test_positional_no_spaces_compact() {
let input = "{{replace .Tag \"v\" \"\"}}";
let result = preprocess(input);
assert_eq!(result, "{{replace(s=Tag, old=\"v\", new=\"\")}}");
}
#[test]
fn test_optional_chaining_dot_survives_go_leading_dot_strip() {
let input = "{{ Some?.Missing or \"fallback\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Some?.Missing or \"fallback\" }}");
}
#[test]
fn test_unrelated_expression_unchanged() {
let input = "{{ Version }}";
let result = preprocess(input);
assert_eq!(result, "{{ Version }}");
}
#[test]
fn test_unrelated_filter_unchanged() {
let input = "{{ Version | upper }}";
let result = preprocess(input);
assert_eq!(result, "{{ Version | upper }}");
}
#[test]
fn test_positional_replace_whitespace_control() {
let input = "{{- replace Version \"v\" \"\" -}}";
let result = preprocess(input);
assert_eq!(result, "{{- replace(s=Version, old=\"v\", new=\"\") -}}");
}
#[test]
fn test_positional_replace_whitespace_control_left_only() {
let input = "{{- replace Version \"v\" \"\" }}";
let result = preprocess(input);
assert_eq!(result, "{{- replace(s=Version, old=\"v\", new=\"\") }}");
}
#[test]
fn test_chained_named_filter_then_positional_rewrite() {
let input = "{{ Version | trimprefix(prefix=\"v\") | replace \".\" \"-\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ Version | trimprefix(prefix=\"v\") | replace(from=\".\", to=\"-\") }}"
);
}
#[test]
fn test_preprocess_in_with_list_subexpr() {
let input = "{{ in (list \"a\" \"b\" \"c\") \"b\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=[\"a\", \"b\", \"c\"], value=\"b\") }}");
}
#[test]
fn test_preprocess_in_with_variable() {
let input = "{{ in myList \"b\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=myList, value=\"b\") }}");
}
#[test]
fn test_preprocess_in_named_args_unchanged() {
let input = "{{ in(items=[\"a\", \"b\"], value=\"a\") }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_in_with_dot_var() {
let input = "{{ in .MyList \"val\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=MyList, value=\"val\") }}");
}
#[test]
fn test_preprocess_in_control_block() {
let input = "{% if in myList \"b\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if in(items=myList, value=\"b\") %}yes{% endif %}"
);
}
#[test]
fn test_preprocess_list_subexpr_rewrite() {
let input = "{{ in (list \"x\" \"y\") \"x\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=[\"x\", \"y\"], value=\"x\") }}");
}
#[test]
fn test_preprocess_in_control_block_with_list_subexpr() {
let input = "{% if in (list \"a\" \"b\") \"a\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if in(items=[\"a\", \"b\"], value=\"a\") %}yes{% endif %}"
);
}
#[test]
fn test_preprocess_re_replace_all_positional() {
let input = "{{ reReplaceAll \"(.*)\" \"hello\" \"$1-world\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ reReplaceAll(pattern=\"(.*)\", input=\"hello\", replacement=\"$1-world\") }}"
);
}
#[test]
fn test_preprocess_re_replace_all_with_variable() {
let input = "{{ reReplaceAll \"(v)(.*)\" Tag \"prefix-$2\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ reReplaceAll(pattern=\"(v)(.*)\", input=Tag, replacement=\"prefix-$2\") }}"
);
}
#[test]
fn test_preprocess_re_replace_all_named_args_unchanged() {
let input = "{{ reReplaceAll(pattern=\"x\", input=\"ax\", replacement=\"y\") }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_re_replace_all_piped() {
let input = "{{ Message | reReplaceAll \"(.*)\" \"$1-done\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ Message | reReplaceAll(pattern=\"(.*)\", replacement=\"$1-done\") }}"
);
}
#[test]
fn test_preprocess_re_replace_all_control_block() {
let input = "{% if reReplaceAll \"v\" Tag \"\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if reReplaceAll(pattern=\"v\", input=Tag, replacement=\"\") %}yes{% endif %}"
);
}
#[test]
fn test_preprocess_in_piped() {
let input = "{{ myList | in \"val\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ myList | in(value=\"val\") }}");
}
#[test]
fn test_preprocess_list_subexpr_escaped_double_quotes_error_loudly() {
use crate::template::{TemplateVars, render};
let input = r#"{{ in (list "hello \"world\"" "plain") "plain" }}"#;
assert_eq!(preprocess(input), input);
assert!(render(input, &TemplateVars::new()).is_err());
}
#[test]
fn test_preprocess_list_subexpr_escaped_single_quotes_error_loudly() {
use crate::template::{TemplateVars, render};
let input = "{{ in (list 'it\\'s' 'fine') \"fine\" }}";
assert_eq!(preprocess(input), input);
assert!(render(input, &TemplateVars::new()).is_err());
}
#[test]
fn test_preprocess_list_subexpr_mixed_quote_styles() {
let input = "{{ in (list \"double\" 'single' \"another\") \"double\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ in(items=[\"double\", 'single', \"another\"], value=\"double\") }}"
);
}
#[test]
fn test_preprocess_list_subexpr_with_bare_identifier() {
let input = "{{ in (list .Os \"windows\") \"linux\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=[Os, \"windows\"], value=\"linux\") }}");
}
#[test]
fn test_preprocess_list_subexpr_with_dotted_path() {
let input = "{{ in (list .Env.FOO \"fallback\") \"val\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ in(items=[Env.FOO, \"fallback\"], value=\"val\") }}"
);
}
#[test]
fn test_preprocess_list_subexpr_all_bare_identifiers() {
let input = "{{ in (list .Os .Arch) \"linux\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ in(items=[Os, Arch], value=\"linux\") }}");
}
#[test]
fn test_preprocess_list_subexpr_mixed_vars_and_strings() {
let input = "{{ in (list .Os \"windows\" .Arch) \"test\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ in(items=[Os, \"windows\", Arch], value=\"test\") }}"
);
}
#[test]
fn test_preprocess_now_format_go_style() {
let input = "{{ .Now.Format \"2006-01-02\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Now | now_format(format=\"2006-01-02\") }}");
}
#[test]
fn test_preprocess_now_format_no_dot_prefix() {
let input = "{{ Now.Format \"2006-01-02\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Now | now_format(format=\"2006-01-02\") }}");
}
#[test]
fn test_preprocess_now_format_with_time_pattern() {
let input = "{{ .Now.Format \"2006-01-02 15:04:05\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ Now | now_format(format=\"2006-01-02 15:04:05\") }}"
);
}
#[test]
fn test_preprocess_now_format_single_quotes() {
let input = "{{ .Now.Format '2006-01-02' }}";
let result = preprocess(input);
assert_eq!(result, "{{ Now | now_format(format='2006-01-02') }}");
}
#[test]
fn test_preprocess_now_format_whitespace_control() {
let input = "{{- .Now.Format \"2006-01-02\" -}}";
let result = preprocess(input);
assert_eq!(result, "{{- Now | now_format(format=\"2006-01-02\") -}}");
}
#[test]
fn test_preprocess_now_format_compact() {
let input = "{{.Now.Format \"2006-01-02\"}}";
let result = preprocess(input);
assert_eq!(result, "{{Now | now_format(format=\"2006-01-02\")}}");
}
#[test]
fn test_preprocess_now_format_does_not_affect_other_blocks() {
let input = "{{ Version }} - {{ .Now.Format \"2006-01-02\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ Version }} - {{ Now | now_format(format=\"2006-01-02\") }}"
);
}
#[test]
fn test_go_if_end() {
let input = "{{ if .IsSnapshot }}pre{{ end }}";
let result = preprocess(input);
assert_eq!(result, "{% if IsSnapshot %}pre{% endif %}");
}
#[test]
fn test_go_if_else_end() {
let input = "{{ if .IsSnapshot }}pre{{ else }}stable{{ end }}";
let result = preprocess(input);
assert_eq!(result, "{% if IsSnapshot %}pre{% else %}stable{% endif %}");
}
#[test]
fn test_go_if_else_if_end() {
let input =
"{{ if eq .Os \"windows\" }}win{{ else if eq .Os \"darwin\" }}mac{{ else }}linux{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% if Os == \"windows\" %}win{% elif Os == \"darwin\" %}mac{% else %}linux{% endif %}"
);
}
#[test]
fn test_go_range_bare() {
let input = "{{ range .Maintainers }}# {{ . }}{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% for val in Maintainers %}# {{ val }}{% endfor %}"
);
}
#[test]
fn test_go_range_with_variable() {
let input = "{{ range $release := .Packages }}{{ $release.Name }}{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% for release in Packages %}{{ release.Name }}{% endfor %}"
);
}
#[test]
fn test_go_range_kv() {
let input = "{{ range $key, $value := .Checksums }}{{ $value }} {{ $key }}{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% for key, value in Checksums %}{{ value }} {{ key }}{% endfor %}"
);
}
#[test]
fn test_go_with() {
let input = "{{ with .Arm }}v{{ . }}{{ end }}";
let result = preprocess(input);
assert_eq!(result, "{% if Arm %}v{{ Arm }}{% endif %}");
}
#[test]
fn test_go_var_assignment() {
let input = "{{ $m := map \"a\" \"1\" }}{{ index $m \"a\" }}";
let result = preprocess(input);
assert_eq!(
result,
"{% set m = map(pairs=[\"a\", \"1\"]) %}{{ index(collection=m, key=\"a\") }}"
);
}
#[test]
fn test_go_whitespace_trim() {
let input = "{{- if .Cond -}}yes{{- end -}}";
let result = preprocess(input);
assert_eq!(result, "{%- if Cond -%}yes{%- endif -%}");
}
#[test]
fn test_go_nested_if_range() {
let input = "{{ range .Items }}{{ if .Active }}*{{ end }}{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% for val in Items %}{% if Active %}*{% endif %}{% endfor %}"
);
}
#[test]
fn test_go_blocks_plain_expressions_unchanged() {
let input = "{{ .ProjectName }}_{{ .Version }}";
let result = preprocess(input);
assert_eq!(result, "{{ ProjectName }}_{{ Version }}");
}
#[test]
fn test_go_complex_nfpm_template() {
let input = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ if not (eq .Amd64 \"v1\") }}{{ .Amd64 }}{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{{ ProjectName }}_{{ Version }}_{{ Os }}_{{ Arch }}{% if Arm %}v{{ Arm }}{% endif %}{% if not Amd64 == \"v1\" %}{{ Amd64 }}{% endif %}"
);
}
#[test]
fn test_eq_in_if_block() {
let input = "{% if eq Os \"windows\" %}win{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Os == \"windows\" %}win{% endif %}");
}
#[test]
fn test_eq_variadic_three_args() {
let input = r#"{% if eq Os "linux" "darwin" %}unix{% endif %}"#;
let result = preprocess(input);
assert_eq!(
result,
r#"{% if Os == "linux" or Os == "darwin" %}unix{% endif %}"#
);
}
#[test]
fn test_eq_variadic_four_args() {
let input = r#"{% if eq Arch "amd64" "arm64" "386" %}supported{% endif %}"#;
let result = preprocess(input);
assert_eq!(
result,
r#"{% if Arch == "amd64" or Arch == "arm64" or Arch == "386" %}supported{% endif %}"#
);
}
#[test]
fn test_ne_in_if_block() {
let input = "{% if ne Os \"windows\" %}not-win{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Os != \"windows\" %}not-win{% endif %}");
}
#[test]
fn test_gt_in_if_block() {
let input = "{% if gt Major 1 %}gt1{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Major > 1 %}gt1{% endif %}");
}
#[test]
fn test_lt_in_if_block() {
let input = "{% if lt Minor 5 %}lt5{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Minor < 5 %}lt5{% endif %}");
}
#[test]
fn test_ge_in_if_block() {
let input = "{% if ge Patch 3 %}ge3{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Patch >= 3 %}ge3{% endif %}");
}
#[test]
fn test_le_in_if_block() {
let input = "{% if le Patch 3 %}le3{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Patch <= 3 %}le3{% endif %}");
}
#[test]
fn test_eq_with_string_literal() {
let input = "{% if eq Arch \"amd64\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Arch == \"amd64\" %}yes{% endif %}");
}
#[test]
fn test_eq_with_numeric_literal() {
let input = "{% if eq Major 1 %}v1{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Major == 1 %}v1{% endif %}");
}
#[test]
fn test_eq_parenthesized_not() {
let input = "{% if not (eq Os \"windows\") %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if not Os == \"windows\" %}yes{% endif %}");
}
#[test]
fn test_eq_in_elif_block() {
let input = "{% if eq Os \"linux\" %}lin{% elif eq Os \"darwin\" %}mac{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if Os == \"linux\" %}lin{% elif Os == \"darwin\" %}mac{% endif %}"
);
}
#[test]
fn test_eq_in_expression_block() {
let input = "{{ eq Os \"linux\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Os == \"linux\" }}");
}
#[test]
fn test_eq_with_already_stripped_dot_var() {
let input = "{% if eq Os \"windows\" %}win{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Os == \"windows\" %}win{% endif %}");
}
#[test]
fn test_eq_with_dotted_path() {
let input = "{% if eq Env.FOO \"bar\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Env.FOO == \"bar\" %}yes{% endif %}");
}
#[test]
fn test_and_prefix_to_infix() {
let input = "{% if and A B %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if A and B %}yes{% endif %}");
}
#[test]
fn test_or_prefix_to_infix() {
let input = "{% if or A B %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if A or B %}yes{% endif %}");
}
#[test]
fn test_and_with_parenthesized_or() {
let input = "{% if and A (or B C) %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if A and (B or C) %}yes{% endif %}");
}
#[test]
fn test_or_with_parenthesized_eq() {
let input = "{% if or (eq Os \"linux\") (eq Os \"darwin\") %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if Os == \"linux\" or Os == \"darwin\" %}yes{% endif %}"
);
}
#[test]
fn test_len_in_expression() {
let input = "{{ len Items }}";
let result = preprocess(input);
assert_eq!(result, "{{ Items | length }}");
}
#[test]
fn test_len_in_if_block() {
let input = "{% if len Items %}has items{% endif %}";
let result = preprocess(input);
assert_eq!(result, "{% if Items | length %}has items{% endif %}");
}
#[test]
fn test_len_with_dotted_path() {
let input = "{{ len Env.PATH }}";
let result = preprocess(input);
assert_eq!(result, "{{ Env.PATH | length }}");
}
#[test]
fn test_len_does_not_match_partial_word() {
let input = "{{ Items | length }}";
let result = preprocess(input);
assert_eq!(result, "{{ Items | length }}");
}
#[test]
fn test_map_positional_two_args() {
let input = "{{ map \"a\" \"1\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ map(pairs=[\"a\", \"1\"]) }}");
}
#[test]
fn test_map_positional_four_args() {
let input = "{{ map \"a\" \"1\" \"b\" \"2\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ map(pairs=[\"a\", \"1\", \"b\", \"2\"]) }}");
}
#[test]
fn test_map_named_args_unchanged() {
let input = "{{ map(pairs=[\"a\", \"1\"]) }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_map_in_set_block() {
let input = "{% set m = map \"x\" \"y\" %}";
let result = preprocess(input);
assert_eq!(result, "{% set m = map(pairs=[\"x\", \"y\"]) %}");
}
#[test]
fn test_index_positional_two_args() {
let input = "{{ index myMap \"key\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ index(collection=myMap, key=\"key\") }}");
}
#[test]
fn test_index_named_args_unchanged() {
let input = "{{ index(collection=myMap, key=\"key\") }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_index_in_control_block() {
let input = "{% if index myMap \"key\" %}yes{% endif %}";
let result = preprocess(input);
assert_eq!(
result,
"{% if index(collection=myMap, key=\"key\") %}yes{% endif %}"
);
}
#[test]
fn test_go_style_full_pipeline_eq_and_map() {
let input = "{{ $m := map \"a\" \"1\" }}{{ if eq (index $m \"a\") \"1\" }}yes{{ end }}";
let result = preprocess(input);
assert_eq!(
result,
"{% set m = map(pairs=[\"a\", \"1\"]) %}{% if (index m \"a\") == \"1\" %}yes{% endif %}"
);
}
#[test]
fn test_preprocess_positional_time() {
let input = "{{ time \"2006-01-02\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ time(format=\"2006-01-02\") }}");
}
#[test]
fn test_preprocess_slice_three_args() {
let input = "{{ slice Commit 0 7 }}";
let result = preprocess(input);
assert_eq!(result, "{{ Commit | slice(start=0, end=7) }}");
}
#[test]
fn test_preprocess_slice_two_args() {
let input = "{{ slice Commit 0 }}";
let result = preprocess(input);
assert_eq!(result, "{{ Commit | slice(start=0) }}");
}
#[test]
fn test_preprocess_slice_string_literal() {
let input = "{{ slice \"abcdefghij\" 0 7 }}";
let result = preprocess(input);
assert_eq!(result, "{{ \"abcdefghij\" | slice(start=0, end=7) }}");
}
#[test]
fn test_preprocess_slice_named_unchanged() {
let input = "{{ Commit | slice(start=0, end=7) }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_printf_variadic() {
let input = "{{ printf \"%04d\" Patch }}";
let result = preprocess(input);
assert_eq!(result, "{{ printf(format=\"%04d\", args=[Patch]) }}");
}
#[test]
fn test_preprocess_printf_multiple_args() {
let input = "{{ printf \"%s-%d\" Os Patch }}";
let result = preprocess(input);
assert_eq!(result, "{{ printf(format=\"%s-%d\", args=[Os, Patch]) }}");
}
#[test]
fn test_preprocess_printf_no_args() {
let input = "{{ printf \"literal\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ printf(format=\"literal\", args=[]) }}");
}
#[test]
fn test_preprocess_print() {
let input = "{{ print \"a\" \"b\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ print(args=[\"a\", \"b\"]) }}");
}
#[test]
fn test_preprocess_println() {
let input = "{{ println \"x\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ println(args=[\"x\"]) }}");
}
#[test]
fn test_preprocess_printf_named_unchanged() {
let input = "{{ printf(format=\"%d\", args=[Patch]) }}";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_preserves_emoji_in_literal_text() {
let input = "Released with anodizer 🦀";
let result = preprocess(input);
assert!(result.contains('🦀'), "emoji must survive, got: {result:?}");
assert_eq!(result, input);
}
#[test]
fn test_preprocess_preserves_multibyte_mix_in_literal_text() {
let input = "café — 日本語 🚀 end";
let result = preprocess(input);
assert_eq!(result, input);
}
#[test]
fn test_preprocess_preserves_emoji_inside_block_string() {
let input = "{{ printf \"%s\" \"🦀\" }}";
let result = preprocess(input);
assert!(
result.contains('🦀'),
"emoji inside block string must survive, got: {result:?}"
);
}
#[test]
fn test_optional_index_dot_survives_go_leading_dot_strip() {
let input = "{{ Some?[0].Field or \"fallback\" }}";
let result = preprocess(input);
assert_eq!(result, "{{ Some?[0].Field or \"fallback\" }}");
}
#[test]
fn test_plain_index_dot_survives_go_leading_dot_strip() {
let input = "{{ Some[0].Field }}";
let result = preprocess(input);
assert_eq!(result, "{{ Some[0].Field }}");
}
#[test]
fn test_numeric_index_simple() {
assert_eq!(preprocess("{{ list.0 }}"), "{{ list[0] }}");
}
#[test]
fn test_numeric_index_multi_digit() {
assert_eq!(preprocess("{{ list.12 }}"), "{{ list[12] }}");
}
#[test]
fn test_numeric_index_then_field() {
assert_eq!(preprocess("{{ a.0.b }}"), "{{ a[0].b }}");
}
#[test]
fn test_numeric_index_chained_indices() {
assert_eq!(preprocess("{{ a.0.1 }}"), "{{ a[0][1] }}");
}
#[test]
fn test_numeric_index_after_bracket_index() {
assert_eq!(preprocess("{{ x[1].0 }}"), "{{ x[1][0] }}");
}
#[test]
fn test_numeric_index_optional_chaining() {
assert_eq!(preprocess("{{ a?.0 }}"), "{{ a?[0] }}");
}
#[test]
fn test_numeric_index_go_style_leading_dot() {
assert_eq!(
preprocess("{{ .Artifacts.0.Name }}"),
"{{ Artifacts[0].Name }}"
);
}
#[test]
fn test_numeric_index_in_statement_block() {
assert_eq!(
preprocess("{% if list.0 %}x{% endif %}"),
"{% if list[0] %}x{% endif %}"
);
}
#[test]
fn test_numeric_index_float_literal_untouched() {
assert_eq!(preprocess("{{ 1.0 }}"), "{{ 1.0 }}");
assert_eq!(preprocess("{{ 1.5 | round }}"), "{{ 1.5 | round }}");
}
#[test]
fn test_numeric_index_version_literal_untouched() {
assert_eq!(preprocess("{{ 1.2 + 0.5 }}"), "{{ 1.2 + 0.5 }}");
}
#[test]
fn test_numeric_index_inside_string_literal_untouched() {
assert_eq!(preprocess("{{ \"a.0\" }}"), "{{ \"a.0\" }}");
assert_eq!(
preprocess("{{ foo | replace(from=\"v1.0\", to=\"\") }}"),
"{{ foo | replace(from=\"v1.0\", to=\"\") }}"
);
}
#[test]
fn test_numeric_index_identifierish_segment_untouched() {
assert_eq!(preprocess("{{ a.0x }}"), "{{ a.0x }}");
}
#[test]
fn test_numeric_index_outside_blocks_untouched() {
assert_eq!(preprocess("v1.0 of {{ name }}"), "v1.0 of {{ name }}");
}
#[test]
fn test_numeric_index_end_to_end_render() {
use crate::template::{TemplateVars, render};
let mut vars = TemplateVars::new();
vars.set_structured("list", serde_json::json!(["first", "second"]));
vars.set_structured("items", serde_json::json!([{"name": "n0"}]));
assert_eq!(render("{{ list.0 }}", &vars).unwrap(), "first");
assert_eq!(render("{{ items.0.name }}", &vars).unwrap(), "n0");
assert_eq!(render("{{ list.1 | upper }}", &vars).unwrap(), "SECOND");
}
#[test]
fn test_backtick_string_skipped_by_numeric_index_pass() {
assert_eq!(preprocess("{{ `v1.0` }}"), "{{ `v1.0` }}");
}
#[test]
fn test_backtick_string_skipped_by_dollar_strip() {
assert_eq!(preprocess("{{ `$foo` }}"), "{{ `$foo` }}");
}
#[test]
fn test_backtick_string_skipped_by_dot_strip() {
assert_eq!(preprocess("{{ `.Field` }}"), "{{ `.Field` }}");
}
#[test]
fn test_backtick_filter_arg_content_untouched() {
let input = "{{ 'v1.0-x' | replace(from=`v1.0`, to=\"Z\") }}";
assert_eq!(preprocess(input), input);
}
#[test]
fn test_string_closes_at_first_quote_even_after_backslash() {
let input = r"{{ 'Q\' ~ 'v1.0' }}";
assert_eq!(preprocess(input), input);
}
#[test]
fn test_multiline_block_dot_strip_applies() {
assert_eq!(preprocess("{{\n .Version }}"), "{{\n Version }}");
}
#[test]
fn test_multiline_block_dollar_strip_applies() {
assert_eq!(preprocess("{{\n $foo }}"), "{{\n foo }}");
}
#[test]
fn test_multiline_block_builtin_rewrite_applies() {
assert_eq!(
preprocess("{% if eq Os \"linux\"\n%}yes{% endif %}"),
"{% if Os == \"linux\"\n%}yes{% endif %}"
);
}
#[test]
fn test_multiline_block_method_call_rewrite_applies() {
assert_eq!(
preprocess("{{\n .Now.Format \"2006-01-02\" }}"),
"{{\n Now | now_format(format=\"2006-01-02\") }}"
);
}
#[test]
fn test_multiline_block_numeric_index_rewrite_applies() {
assert_eq!(preprocess("{{\n list.0 }}"), "{{\n list[0] }}");
}