@owenlamont/ryl 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/.github/CODEOWNERS +1 -0
  2. package/.github/dependabot.yml +13 -0
  3. package/.github/workflows/ci.yml +107 -0
  4. package/.github/workflows/release.yml +613 -0
  5. package/.github/workflows/update_dependencies.yml +61 -0
  6. package/.github/workflows/update_linters.yml +56 -0
  7. package/.pre-commit-config.yaml +87 -0
  8. package/.yamllint +4 -0
  9. package/AGENTS.md +200 -0
  10. package/Cargo.lock +908 -0
  11. package/Cargo.toml +32 -0
  12. package/LICENSE +21 -0
  13. package/README.md +230 -0
  14. package/bin/ryl.js +1 -0
  15. package/clippy.toml +1 -0
  16. package/docs/config-presets.md +100 -0
  17. package/img/benchmark-5x5-5runs.svg +2176 -0
  18. package/package.json +28 -0
  19. package/pyproject.toml +42 -0
  20. package/ruff.toml +107 -0
  21. package/rumdl.toml +20 -0
  22. package/rust-toolchain.toml +3 -0
  23. package/rustfmt.toml +3 -0
  24. package/scripts/benchmark_perf_vs_yamllint.py +400 -0
  25. package/scripts/coverage-missing.ps1 +80 -0
  26. package/scripts/coverage-missing.sh +60 -0
  27. package/src/bin/discover_config_bin.rs +24 -0
  28. package/src/cli_support.rs +33 -0
  29. package/src/conf/mod.rs +85 -0
  30. package/src/config.rs +2099 -0
  31. package/src/decoder.rs +326 -0
  32. package/src/discover.rs +31 -0
  33. package/src/lib.rs +19 -0
  34. package/src/lint.rs +558 -0
  35. package/src/main.rs +535 -0
  36. package/src/migrate.rs +233 -0
  37. package/src/rules/anchors.rs +517 -0
  38. package/src/rules/braces.rs +77 -0
  39. package/src/rules/brackets.rs +77 -0
  40. package/src/rules/colons.rs +475 -0
  41. package/src/rules/commas.rs +372 -0
  42. package/src/rules/comments.rs +299 -0
  43. package/src/rules/comments_indentation.rs +243 -0
  44. package/src/rules/document_end.rs +175 -0
  45. package/src/rules/document_start.rs +84 -0
  46. package/src/rules/empty_lines.rs +152 -0
  47. package/src/rules/empty_values.rs +255 -0
  48. package/src/rules/float_values.rs +259 -0
  49. package/src/rules/flow_collection.rs +562 -0
  50. package/src/rules/hyphens.rs +104 -0
  51. package/src/rules/indentation.rs +803 -0
  52. package/src/rules/key_duplicates.rs +218 -0
  53. package/src/rules/key_ordering.rs +303 -0
  54. package/src/rules/line_length.rs +326 -0
  55. package/src/rules/mod.rs +25 -0
  56. package/src/rules/new_line_at_end_of_file.rs +23 -0
  57. package/src/rules/new_lines.rs +95 -0
  58. package/src/rules/octal_values.rs +121 -0
  59. package/src/rules/quoted_strings.rs +577 -0
  60. package/src/rules/span_utils.rs +37 -0
  61. package/src/rules/trailing_spaces.rs +65 -0
  62. package/src/rules/truthy.rs +420 -0
  63. package/tests/brackets_carriage_return.rs +114 -0
  64. package/tests/build_global_cfg_error.rs +23 -0
  65. package/tests/cli_anchors_rule.rs +143 -0
  66. package/tests/cli_braces_rule.rs +104 -0
  67. package/tests/cli_brackets_rule.rs +104 -0
  68. package/tests/cli_colons_rule.rs +65 -0
  69. package/tests/cli_commas_rule.rs +104 -0
  70. package/tests/cli_comments_indentation_rule.rs +61 -0
  71. package/tests/cli_comments_rule.rs +67 -0
  72. package/tests/cli_config_data_error.rs +30 -0
  73. package/tests/cli_config_flags.rs +66 -0
  74. package/tests/cli_config_migrate.rs +229 -0
  75. package/tests/cli_document_end_rule.rs +92 -0
  76. package/tests/cli_document_start_rule.rs +92 -0
  77. package/tests/cli_empty_lines_rule.rs +87 -0
  78. package/tests/cli_empty_values_rule.rs +68 -0
  79. package/tests/cli_env_config.rs +34 -0
  80. package/tests/cli_exit_and_errors.rs +41 -0
  81. package/tests/cli_file_encoding.rs +203 -0
  82. package/tests/cli_float_values_rule.rs +64 -0
  83. package/tests/cli_format_options.rs +316 -0
  84. package/tests/cli_global_cfg_relaxed.rs +20 -0
  85. package/tests/cli_hyphens_rule.rs +104 -0
  86. package/tests/cli_indentation_rule.rs +65 -0
  87. package/tests/cli_invalid_project_config.rs +39 -0
  88. package/tests/cli_key_duplicates_rule.rs +104 -0
  89. package/tests/cli_key_ordering_rule.rs +59 -0
  90. package/tests/cli_line_length_rule.rs +85 -0
  91. package/tests/cli_list_files.rs +29 -0
  92. package/tests/cli_new_line_rule.rs +141 -0
  93. package/tests/cli_new_lines_rule.rs +119 -0
  94. package/tests/cli_octal_values_rule.rs +60 -0
  95. package/tests/cli_quoted_strings_rule.rs +47 -0
  96. package/tests/cli_toml_config.rs +119 -0
  97. package/tests/cli_trailing_spaces_rule.rs +77 -0
  98. package/tests/cli_truthy_rule.rs +83 -0
  99. package/tests/cli_yaml_files_negation.rs +45 -0
  100. package/tests/colons_rule.rs +303 -0
  101. package/tests/common/compat.rs +114 -0
  102. package/tests/common/fake_env.rs +93 -0
  103. package/tests/common/mod.rs +1 -0
  104. package/tests/conf_builtin.rs +9 -0
  105. package/tests/config_anchors.rs +84 -0
  106. package/tests/config_braces.rs +121 -0
  107. package/tests/config_brackets.rs +127 -0
  108. package/tests/config_commas.rs +79 -0
  109. package/tests/config_comments.rs +65 -0
  110. package/tests/config_comments_indentation.rs +20 -0
  111. package/tests/config_deep_merge_nonstring_key.rs +24 -0
  112. package/tests/config_document_end.rs +54 -0
  113. package/tests/config_document_start.rs +55 -0
  114. package/tests/config_empty_lines.rs +48 -0
  115. package/tests/config_empty_values.rs +35 -0
  116. package/tests/config_env_errors.rs +23 -0
  117. package/tests/config_env_invalid_inline.rs +15 -0
  118. package/tests/config_env_missing.rs +63 -0
  119. package/tests/config_env_shim.rs +301 -0
  120. package/tests/config_explicit_file_parse_error.rs +55 -0
  121. package/tests/config_extended_features.rs +225 -0
  122. package/tests/config_extends_inline.rs +185 -0
  123. package/tests/config_extends_sequence.rs +18 -0
  124. package/tests/config_find_project_home_boundary.rs +54 -0
  125. package/tests/config_find_project_two_files_in_cwd.rs +47 -0
  126. package/tests/config_float_values.rs +34 -0
  127. package/tests/config_from_yaml_paths.rs +32 -0
  128. package/tests/config_hyphens.rs +51 -0
  129. package/tests/config_ignore_errors.rs +243 -0
  130. package/tests/config_ignore_overrides.rs +83 -0
  131. package/tests/config_indentation.rs +65 -0
  132. package/tests/config_invalid_globs.rs +16 -0
  133. package/tests/config_invalid_types.rs +19 -0
  134. package/tests/config_key_duplicates.rs +34 -0
  135. package/tests/config_key_ordering.rs +70 -0
  136. package/tests/config_line_length.rs +65 -0
  137. package/tests/config_locale.rs +111 -0
  138. package/tests/config_merge.rs +26 -0
  139. package/tests/config_new_lines.rs +89 -0
  140. package/tests/config_octal_values.rs +33 -0
  141. package/tests/config_quoted_strings.rs +195 -0
  142. package/tests/config_rule_level.rs +147 -0
  143. package/tests/config_rules_non_string_keys.rs +23 -0
  144. package/tests/config_scalar_overrides.rs +27 -0
  145. package/tests/config_to_toml.rs +110 -0
  146. package/tests/config_toml_coverage.rs +80 -0
  147. package/tests/config_toml_discovery.rs +304 -0
  148. package/tests/config_trailing_spaces.rs +152 -0
  149. package/tests/config_truthy.rs +77 -0
  150. package/tests/config_yaml_files.rs +62 -0
  151. package/tests/config_yaml_files_all_non_string.rs +15 -0
  152. package/tests/config_yaml_files_empty.rs +30 -0
  153. package/tests/coverage_commas.rs +46 -0
  154. package/tests/decoder_decode.rs +338 -0
  155. package/tests/discover_config_bin_all.rs +66 -0
  156. package/tests/discover_config_bin_env_invalid_yaml.rs +26 -0
  157. package/tests/discover_config_bin_project_config_parse_error.rs +24 -0
  158. package/tests/discover_config_bin_user_global_error.rs +26 -0
  159. package/tests/discover_module.rs +30 -0
  160. package/tests/discover_per_file_dir.rs +10 -0
  161. package/tests/discover_per_file_project_config_error.rs +21 -0
  162. package/tests/float_values.rs +43 -0
  163. package/tests/lint_multi_errors.rs +32 -0
  164. package/tests/main_yaml_ok_filtering.rs +30 -0
  165. package/tests/migrate_module.rs +259 -0
  166. package/tests/resolve_ctx_empty_parent.rs +16 -0
  167. package/tests/rule_anchors.rs +442 -0
  168. package/tests/rule_braces.rs +258 -0
  169. package/tests/rule_brackets.rs +217 -0
  170. package/tests/rule_commas.rs +205 -0
  171. package/tests/rule_comments.rs +197 -0
  172. package/tests/rule_comments_indentation.rs +127 -0
  173. package/tests/rule_document_end.rs +118 -0
  174. package/tests/rule_document_start.rs +60 -0
  175. package/tests/rule_empty_lines.rs +96 -0
  176. package/tests/rule_empty_values.rs +102 -0
  177. package/tests/rule_float_values.rs +109 -0
  178. package/tests/rule_hyphens.rs +65 -0
  179. package/tests/rule_indentation.rs +455 -0
  180. package/tests/rule_key_duplicates.rs +76 -0
  181. package/tests/rule_key_ordering.rs +207 -0
  182. package/tests/rule_line_length.rs +200 -0
  183. package/tests/rule_new_lines.rs +51 -0
  184. package/tests/rule_octal_values.rs +53 -0
  185. package/tests/rule_quoted_strings.rs +290 -0
  186. package/tests/rule_trailing_spaces.rs +41 -0
  187. package/tests/rule_truthy.rs +236 -0
  188. package/tests/user_global_invalid_yaml.rs +32 -0
  189. package/tests/yamllint_compat_anchors.rs +280 -0
  190. package/tests/yamllint_compat_braces.rs +411 -0
  191. package/tests/yamllint_compat_brackets.rs +364 -0
  192. package/tests/yamllint_compat_colons.rs +298 -0
  193. package/tests/yamllint_compat_colors.rs +80 -0
  194. package/tests/yamllint_compat_commas.rs +375 -0
  195. package/tests/yamllint_compat_comments.rs +167 -0
  196. package/tests/yamllint_compat_comments_indentation.rs +281 -0
  197. package/tests/yamllint_compat_config.rs +170 -0
  198. package/tests/yamllint_compat_document_end.rs +243 -0
  199. package/tests/yamllint_compat_document_start.rs +136 -0
  200. package/tests/yamllint_compat_empty_lines.rs +117 -0
  201. package/tests/yamllint_compat_empty_values.rs +179 -0
  202. package/tests/yamllint_compat_float_values.rs +216 -0
  203. package/tests/yamllint_compat_hyphens.rs +223 -0
  204. package/tests/yamllint_compat_indentation.rs +398 -0
  205. package/tests/yamllint_compat_key_duplicates.rs +139 -0
  206. package/tests/yamllint_compat_key_ordering.rs +170 -0
  207. package/tests/yamllint_compat_line_length.rs +375 -0
  208. package/tests/yamllint_compat_list.rs +127 -0
  209. package/tests/yamllint_compat_new_line.rs +133 -0
  210. package/tests/yamllint_compat_newline_types.rs +185 -0
  211. package/tests/yamllint_compat_octal_values.rs +172 -0
  212. package/tests/yamllint_compat_quoted_strings.rs +154 -0
  213. package/tests/yamllint_compat_syntax.rs +200 -0
  214. package/tests/yamllint_compat_trailing_spaces.rs +162 -0
  215. package/tests/yamllint_compat_truthy.rs +130 -0
  216. package/tests/yamllint_compat_yaml_files.rs +81 -0
  217. package/typos.toml +2 -0
@@ -0,0 +1,121 @@
1
+ use ryl::config::YamlLintConfig;
2
+ use ryl::rules::braces::{Config as BracesConfig, Forbid};
3
+
4
+ fn parse_config(input: &str) -> YamlLintConfig {
5
+ YamlLintConfig::from_yaml_str(input).expect("config should parse")
6
+ }
7
+
8
+ #[test]
9
+ fn braces_options_are_parsed() {
10
+ let cfg = parse_config(
11
+ "rules:\n braces:\n forbid: non-empty\n min-spaces-inside: 1\n max-spaces-inside: 2\n min-spaces-inside-empty: 3\n max-spaces-inside-empty: 4\n",
12
+ );
13
+
14
+ let rule_cfg = BracesConfig::resolve(&cfg);
15
+ assert_eq!(rule_cfg.forbid(), Forbid::NonEmpty);
16
+ assert_eq!(rule_cfg.min_spaces_inside(), 1);
17
+ assert_eq!(rule_cfg.max_spaces_inside(), 2);
18
+ assert_eq!(rule_cfg.effective_min_empty(), 3);
19
+ assert_eq!(rule_cfg.effective_max_empty(), 4);
20
+ }
21
+
22
+ #[test]
23
+ fn braces_empty_overrides_fallback_to_main_values() {
24
+ let cfg = parse_config(
25
+ "rules:\n braces:\n min-spaces-inside: 2\n max-spaces-inside: 3\n",
26
+ );
27
+
28
+ let rule_cfg = BracesConfig::resolve(&cfg);
29
+ assert_eq!(rule_cfg.effective_min_empty(), 2);
30
+ assert_eq!(rule_cfg.effective_max_empty(), 3);
31
+ }
32
+
33
+ #[test]
34
+ fn braces_invalid_forbid_value_is_rejected() {
35
+ let err = YamlLintConfig::from_yaml_str("rules:\n braces:\n forbid: maybe\n")
36
+ .expect_err("config should fail");
37
+ assert!(
38
+ err.contains("option \"forbid\" of \"braces\" should be bool or \"non-empty\""),
39
+ "unexpected error: {err}"
40
+ );
41
+ }
42
+
43
+ #[test]
44
+ fn braces_invalid_numeric_option_is_rejected() {
45
+ let err = YamlLintConfig::from_yaml_str(
46
+ "rules:\n braces:\n min-spaces-inside: foo\n",
47
+ )
48
+ .expect_err("config should fail");
49
+ assert!(
50
+ err.contains("option \"min-spaces-inside\" of \"braces\" should be int"),
51
+ "unexpected error: {err}"
52
+ );
53
+ }
54
+
55
+ #[test]
56
+ fn braces_invalid_max_option_is_rejected() {
57
+ let err = YamlLintConfig::from_yaml_str(
58
+ "rules:\n braces:\n max-spaces-inside: foo\n",
59
+ )
60
+ .expect_err("config should fail");
61
+ assert!(
62
+ err.contains("option \"max-spaces-inside\" of \"braces\" should be int"),
63
+ "unexpected error: {err}"
64
+ );
65
+ }
66
+
67
+ #[test]
68
+ fn braces_invalid_empty_max_option_is_rejected() {
69
+ let err = YamlLintConfig::from_yaml_str(
70
+ "rules:\n braces:\n max-spaces-inside-empty: foo\n",
71
+ )
72
+ .expect_err("config should fail");
73
+ assert!(
74
+ err.contains("option \"max-spaces-inside-empty\" of \"braces\" should be int"),
75
+ "unexpected error: {err}"
76
+ );
77
+ }
78
+
79
+ #[test]
80
+ fn braces_invalid_empty_min_option_is_rejected() {
81
+ let err = YamlLintConfig::from_yaml_str(
82
+ "rules:\n braces:\n min-spaces-inside-empty: foo\n",
83
+ )
84
+ .expect_err("config should fail");
85
+ assert!(
86
+ err.contains("option \"min-spaces-inside-empty\" of \"braces\" should be int"),
87
+ "unexpected error: {err}"
88
+ );
89
+ }
90
+
91
+ #[test]
92
+ fn braces_unknown_string_option_is_rejected() {
93
+ let err = YamlLintConfig::from_yaml_str(
94
+ "rules:\n braces:\n unexpected-option: true\n",
95
+ )
96
+ .expect_err("config should fail");
97
+ assert!(
98
+ err.contains(
99
+ "invalid config: unknown option \"unexpected-option\" for rule \"braces\""
100
+ ),
101
+ "unexpected error: {err}"
102
+ );
103
+ }
104
+
105
+ #[test]
106
+ fn braces_non_string_key_reports_error() {
107
+ let err = YamlLintConfig::from_yaml_str("rules:\n braces:\n 1: true\n")
108
+ .expect_err("config should fail");
109
+ assert!(
110
+ err.contains("invalid config: unknown option \"1\" for rule \"braces\""),
111
+ "unexpected error: {err}"
112
+ );
113
+ }
114
+
115
+ #[test]
116
+ fn forbid_false_maps_to_none() {
117
+ let cfg = parse_config("rules:\n braces:\n forbid: false\n");
118
+
119
+ let rule_cfg = BracesConfig::resolve(&cfg);
120
+ assert_eq!(rule_cfg.forbid(), Forbid::None);
121
+ }
@@ -0,0 +1,127 @@
1
+ use ryl::config::YamlLintConfig;
2
+ use ryl::rules::brackets::{Config as BracketsConfig, Forbid};
3
+
4
+ fn parse_config(input: &str) -> YamlLintConfig {
5
+ YamlLintConfig::from_yaml_str(input).expect("config should parse")
6
+ }
7
+
8
+ #[test]
9
+ fn brackets_options_are_parsed() {
10
+ let cfg = parse_config(
11
+ "rules:\n brackets:\n forbid: non-empty\n min-spaces-inside: 1\n max-spaces-inside: 2\n min-spaces-inside-empty: 3\n max-spaces-inside-empty: 4\n",
12
+ );
13
+
14
+ let rule_cfg = BracketsConfig::resolve(&cfg);
15
+ assert_eq!(rule_cfg.forbid(), Forbid::NonEmpty);
16
+ assert_eq!(rule_cfg.min_spaces_inside(), 1);
17
+ assert_eq!(rule_cfg.max_spaces_inside(), 2);
18
+ assert_eq!(rule_cfg.effective_min_empty(), 3);
19
+ assert_eq!(rule_cfg.effective_max_empty(), 4);
20
+ }
21
+
22
+ #[test]
23
+ fn brackets_empty_overrides_fallback_to_main_values() {
24
+ let cfg = parse_config(
25
+ "rules:\n brackets:\n min-spaces-inside: 2\n max-spaces-inside: 3\n",
26
+ );
27
+
28
+ let rule_cfg = BracketsConfig::resolve(&cfg);
29
+ assert_eq!(rule_cfg.effective_min_empty(), 2);
30
+ assert_eq!(rule_cfg.effective_max_empty(), 3);
31
+ }
32
+
33
+ #[test]
34
+ fn brackets_invalid_forbid_value_is_rejected() {
35
+ let err = YamlLintConfig::from_yaml_str("rules:\n brackets:\n forbid: maybe\n")
36
+ .expect_err("config should fail");
37
+ assert!(
38
+ err.contains(
39
+ "option \"forbid\" of \"brackets\" should be bool or \"non-empty\""
40
+ ),
41
+ "unexpected error: {err}"
42
+ );
43
+ }
44
+
45
+ #[test]
46
+ fn brackets_invalid_numeric_option_is_rejected() {
47
+ let err = YamlLintConfig::from_yaml_str(
48
+ "rules:\n brackets:\n min-spaces-inside: foo\n",
49
+ )
50
+ .expect_err("config should fail");
51
+ assert!(
52
+ err.contains("option \"min-spaces-inside\" of \"brackets\" should be int"),
53
+ "unexpected error: {err}"
54
+ );
55
+ }
56
+
57
+ #[test]
58
+ fn brackets_invalid_max_option_is_rejected() {
59
+ let err = YamlLintConfig::from_yaml_str(
60
+ "rules:\n brackets:\n max-spaces-inside: foo\n",
61
+ )
62
+ .expect_err("config should fail");
63
+ assert!(
64
+ err.contains("option \"max-spaces-inside\" of \"brackets\" should be int"),
65
+ "unexpected error: {err}"
66
+ );
67
+ }
68
+
69
+ #[test]
70
+ fn brackets_invalid_empty_max_option_is_rejected() {
71
+ let err = YamlLintConfig::from_yaml_str(
72
+ "rules:\n brackets:\n max-spaces-inside-empty: foo\n",
73
+ )
74
+ .expect_err("config should fail");
75
+ assert!(
76
+ err.contains(
77
+ "option \"max-spaces-inside-empty\" of \"brackets\" should be int"
78
+ ),
79
+ "unexpected error: {err}"
80
+ );
81
+ }
82
+
83
+ #[test]
84
+ fn brackets_invalid_empty_min_option_is_rejected() {
85
+ let err = YamlLintConfig::from_yaml_str(
86
+ "rules:\n brackets:\n min-spaces-inside-empty: foo\n",
87
+ )
88
+ .expect_err("config should fail");
89
+ assert!(
90
+ err.contains(
91
+ "option \"min-spaces-inside-empty\" of \"brackets\" should be int"
92
+ ),
93
+ "unexpected error: {err}"
94
+ );
95
+ }
96
+
97
+ #[test]
98
+ fn brackets_unknown_string_option_is_rejected() {
99
+ let err = YamlLintConfig::from_yaml_str(
100
+ "rules:\n brackets:\n unexpected-option: true\n",
101
+ )
102
+ .expect_err("config should fail");
103
+ assert!(
104
+ err.contains(
105
+ "invalid config: unknown option \"unexpected-option\" for rule \"brackets\""
106
+ ),
107
+ "unexpected error: {err}"
108
+ );
109
+ }
110
+
111
+ #[test]
112
+ fn brackets_non_string_key_reports_error() {
113
+ let err = YamlLintConfig::from_yaml_str("rules:\n brackets:\n 1: true\n")
114
+ .expect_err("config should fail");
115
+ assert!(
116
+ err.contains("invalid config: unknown option \"1\" for rule \"brackets\""),
117
+ "unexpected error: {err}"
118
+ );
119
+ }
120
+
121
+ #[test]
122
+ fn forbid_false_maps_to_none() {
123
+ let cfg = parse_config("rules:\n brackets:\n forbid: false\n");
124
+
125
+ let rule_cfg = BracketsConfig::resolve(&cfg);
126
+ assert_eq!(rule_cfg.forbid(), Forbid::None);
127
+ }
@@ -0,0 +1,79 @@
1
+ use ryl::config::YamlLintConfig;
2
+ use ryl::rules::commas::Config;
3
+
4
+ #[test]
5
+ fn rejects_unknown_option() {
6
+ let err = YamlLintConfig::from_yaml_str("rules:\n commas:\n unexpected: 1\n")
7
+ .unwrap_err();
8
+ assert_eq!(
9
+ err,
10
+ "invalid config: unknown option \"unexpected\" for rule \"commas\""
11
+ );
12
+ }
13
+
14
+ #[test]
15
+ fn rejects_non_integer_max_spaces_before() {
16
+ let err =
17
+ YamlLintConfig::from_yaml_str("rules:\n commas:\n max-spaces-before: []\n")
18
+ .unwrap_err();
19
+ assert_eq!(
20
+ err,
21
+ "invalid config: option \"max-spaces-before\" of \"commas\" should be int"
22
+ );
23
+ }
24
+
25
+ #[test]
26
+ fn rejects_non_integer_min_spaces_after() {
27
+ let err = YamlLintConfig::from_yaml_str(
28
+ "rules:\n commas:\n min-spaces-after: true\n",
29
+ )
30
+ .unwrap_err();
31
+ assert_eq!(
32
+ err,
33
+ "invalid config: option \"min-spaces-after\" of \"commas\" should be int"
34
+ );
35
+ }
36
+
37
+ #[test]
38
+ fn rejects_non_integer_max_spaces_after() {
39
+ let err =
40
+ YamlLintConfig::from_yaml_str("rules:\n commas:\n max-spaces-after: []\n")
41
+ .unwrap_err();
42
+ assert_eq!(
43
+ err,
44
+ "invalid config: option \"max-spaces-after\" of \"commas\" should be int"
45
+ );
46
+ }
47
+
48
+ #[test]
49
+ fn rejects_non_string_option_key() {
50
+ let err =
51
+ YamlLintConfig::from_yaml_str("rules:\n commas:\n ? [foo, bar]\n : 1\n")
52
+ .unwrap_err();
53
+ assert_eq!(
54
+ err,
55
+ "invalid config: unknown option \"Sequence([Value(String(\"foo\")), Value(String(\"bar\"))])\" for rule \"commas\""
56
+ );
57
+ }
58
+
59
+ #[test]
60
+ fn resolve_uses_default_values() {
61
+ let cfg = YamlLintConfig::from_yaml_str("rules:\n commas: enable\n")
62
+ .expect("parse config");
63
+ let resolved = Config::resolve(&cfg);
64
+ assert_eq!(resolved.max_spaces_before(), 0);
65
+ assert_eq!(resolved.min_spaces_after(), 1);
66
+ assert_eq!(resolved.max_spaces_after(), 1);
67
+ }
68
+
69
+ #[test]
70
+ fn resolve_reads_configured_values() {
71
+ let cfg = YamlLintConfig::from_yaml_str(
72
+ "rules:\n commas:\n max-spaces-before: 2\n min-spaces-after: 0\n max-spaces-after: -1\n",
73
+ )
74
+ .expect("parse config");
75
+ let resolved = Config::resolve(&cfg);
76
+ assert_eq!(resolved.max_spaces_before(), 2);
77
+ assert_eq!(resolved.min_spaces_after(), 0);
78
+ assert_eq!(resolved.max_spaces_after(), -1);
79
+ }
@@ -0,0 +1,65 @@
1
+ use ryl::config::YamlLintConfig;
2
+
3
+ #[test]
4
+ fn rejects_unknown_option() {
5
+ let err =
6
+ YamlLintConfig::from_yaml_str("rules:\n comments:\n unexpected: true\n")
7
+ .unwrap_err();
8
+ assert_eq!(
9
+ err,
10
+ "invalid config: unknown option \"unexpected\" for rule \"comments\""
11
+ );
12
+ }
13
+
14
+ #[test]
15
+ fn rejects_non_bool_require_starting_space() {
16
+ let err = YamlLintConfig::from_yaml_str(
17
+ "rules:\n comments:\n require-starting-space: 1\n",
18
+ )
19
+ .unwrap_err();
20
+ assert_eq!(
21
+ err,
22
+ "invalid config: option \"require-starting-space\" of \"comments\" should be bool"
23
+ );
24
+ }
25
+
26
+ #[test]
27
+ fn rejects_non_bool_ignore_shebangs() {
28
+ let err =
29
+ YamlLintConfig::from_yaml_str("rules:\n comments:\n ignore-shebangs: []\n")
30
+ .unwrap_err();
31
+ assert_eq!(
32
+ err,
33
+ "invalid config: option \"ignore-shebangs\" of \"comments\" should be bool"
34
+ );
35
+ }
36
+
37
+ #[test]
38
+ fn rejects_non_integer_min_spaces() {
39
+ let err = YamlLintConfig::from_yaml_str(
40
+ "rules:\n comments:\n min-spaces-from-content: true\n",
41
+ )
42
+ .unwrap_err();
43
+ assert_eq!(
44
+ err,
45
+ "invalid config: option \"min-spaces-from-content\" of \"comments\" should be int"
46
+ );
47
+ }
48
+
49
+ #[test]
50
+ fn accepts_valid_configuration() {
51
+ let cfg = YamlLintConfig::from_yaml_str(
52
+ "rules:\n comments:\n require-starting-space: false\n ignore-shebangs: false\n min-spaces-from-content: 4\n",
53
+ )
54
+ .expect("configuration should parse");
55
+ assert!(cfg.rule_names().iter().any(|name| name == "comments"));
56
+ }
57
+
58
+ #[test]
59
+ fn accepts_negative_min_spaces() {
60
+ let cfg = YamlLintConfig::from_yaml_str(
61
+ "rules:\n comments:\n min-spaces-from-content: -1\n",
62
+ )
63
+ .expect("configuration should parse");
64
+ assert!(cfg.rule_names().iter().any(|name| name == "comments"));
65
+ }
@@ -0,0 +1,20 @@
1
+ use ryl::config::YamlLintConfig;
2
+
3
+ #[test]
4
+ fn error_on_unknown_option() {
5
+ let err = YamlLintConfig::from_yaml_str(
6
+ "rules:\n comments-indentation:\n foo: true\n",
7
+ )
8
+ .unwrap_err();
9
+ assert_eq!(
10
+ err,
11
+ "invalid config: unknown option \"foo\" for rule \"comments-indentation\""
12
+ );
13
+ }
14
+
15
+ #[test]
16
+ fn accepts_boolean_toggle() {
17
+ let cfg = YamlLintConfig::from_yaml_str("rules:\n comments-indentation: false\n")
18
+ .expect("config should parse");
19
+ assert!(cfg.rule_level("comments-indentation").is_none());
20
+ }
@@ -0,0 +1,24 @@
1
+ use ryl::config::{Overrides, discover_config};
2
+
3
+ #[test]
4
+ fn deep_merge_skips_non_string_inner_keys() {
5
+ // default has `comments` as a mapping; we override with a mapping that contains
6
+ // a non-string key to trigger `continue` inside deep_merge_yaml_owned.
7
+ let cfg = r#"
8
+ extends: default
9
+ rules:
10
+ comments:
11
+ ? [1, 2]
12
+ : 9
13
+ level: error
14
+ "#;
15
+ let ctx = discover_config(
16
+ &[],
17
+ &Overrides {
18
+ config_file: None,
19
+ config_data: Some(cfg.into()),
20
+ },
21
+ )
22
+ .expect("parse");
23
+ assert!(ctx.config.rule_names().iter().any(|r| r == "comments"));
24
+ }
@@ -0,0 +1,54 @@
1
+ use ryl::config::YamlLintConfig;
2
+ use ryl::rules::document_end::Config;
3
+
4
+ #[test]
5
+ fn resolve_defaults_to_present_true() {
6
+ let cfg = YamlLintConfig::from_yaml_str("rules:\n document-end: enable\n")
7
+ .expect("config parses");
8
+ let rule_cfg = Config::resolve(&cfg);
9
+ assert!(rule_cfg.requires_marker(), "default should require marker");
10
+ }
11
+
12
+ #[test]
13
+ fn resolve_reads_present_override() {
14
+ let cfg =
15
+ YamlLintConfig::from_yaml_str("rules:\n document-end:\n present: false\n")
16
+ .expect("config parses");
17
+ let rule_cfg = Config::resolve(&cfg);
18
+ assert!(
19
+ !rule_cfg.requires_marker(),
20
+ "override should disable marker"
21
+ );
22
+ }
23
+
24
+ #[test]
25
+ fn invalid_present_value_is_rejected() {
26
+ let err =
27
+ YamlLintConfig::from_yaml_str("rules:\n document-end:\n present: 1\n")
28
+ .expect_err("invalid bool should fail");
29
+ assert_eq!(
30
+ err,
31
+ "invalid config: option \"present\" of \"document-end\" should be bool"
32
+ );
33
+ }
34
+
35
+ #[test]
36
+ fn unknown_option_is_rejected() {
37
+ let err =
38
+ YamlLintConfig::from_yaml_str("rules:\n document-end:\n extra: true\n")
39
+ .expect_err("unknown option should fail");
40
+ assert_eq!(
41
+ err,
42
+ "invalid config: unknown option \"extra\" for rule \"document-end\""
43
+ );
44
+ }
45
+
46
+ #[test]
47
+ fn non_string_option_key_is_rejected() {
48
+ let err = YamlLintConfig::from_yaml_str("rules:\n document-end:\n 1: true\n")
49
+ .expect_err("non string key should fail");
50
+ assert_eq!(
51
+ err,
52
+ "invalid config: unknown option \"1\" for rule \"document-end\""
53
+ );
54
+ }
@@ -0,0 +1,55 @@
1
+ use ryl::config::YamlLintConfig;
2
+ use ryl::rules::document_start::Config;
3
+
4
+ #[test]
5
+ fn resolve_defaults_to_present_true() {
6
+ let cfg = YamlLintConfig::from_yaml_str("rules:\n document-start: enable\n")
7
+ .expect("config parses");
8
+ let rule_cfg = Config::resolve(&cfg);
9
+ assert!(rule_cfg.requires_marker(), "default should require marker");
10
+ }
11
+
12
+ #[test]
13
+ fn resolve_reads_present_override() {
14
+ let cfg = YamlLintConfig::from_yaml_str(
15
+ "rules:\n document-start:\n present: false\n",
16
+ )
17
+ .expect("config parses");
18
+ let rule_cfg = Config::resolve(&cfg);
19
+ assert!(
20
+ !rule_cfg.requires_marker(),
21
+ "override should disable marker"
22
+ );
23
+ }
24
+
25
+ #[test]
26
+ fn invalid_present_value_is_rejected() {
27
+ let err =
28
+ YamlLintConfig::from_yaml_str("rules:\n document-start:\n present: 1\n")
29
+ .expect_err("invalid bool should fail");
30
+ assert_eq!(
31
+ err,
32
+ "invalid config: option \"present\" of \"document-start\" should be bool"
33
+ );
34
+ }
35
+
36
+ #[test]
37
+ fn unknown_option_is_rejected() {
38
+ let err =
39
+ YamlLintConfig::from_yaml_str("rules:\n document-start:\n extra: true\n")
40
+ .expect_err("unknown option should fail");
41
+ assert_eq!(
42
+ err,
43
+ "invalid config: unknown option \"extra\" for rule \"document-start\""
44
+ );
45
+ }
46
+
47
+ #[test]
48
+ fn non_string_option_key_is_rejected() {
49
+ let err = YamlLintConfig::from_yaml_str("rules:\n document-start:\n 1: true\n")
50
+ .expect_err("non string key should fail");
51
+ assert_eq!(
52
+ err,
53
+ "invalid config: unknown option \"1\" for rule \"document-start\""
54
+ );
55
+ }
@@ -0,0 +1,48 @@
1
+ use ryl::config::YamlLintConfig;
2
+
3
+ #[test]
4
+ fn error_on_non_integer_limits() {
5
+ let err = YamlLintConfig::from_yaml_str("rules:\n empty-lines:\n max: true\n")
6
+ .unwrap_err();
7
+ assert_eq!(
8
+ err,
9
+ "invalid config: option \"max\" of \"empty-lines\" should be int"
10
+ );
11
+
12
+ let err =
13
+ YamlLintConfig::from_yaml_str("rules:\n empty-lines:\n max-start: false\n")
14
+ .unwrap_err();
15
+ assert_eq!(
16
+ err,
17
+ "invalid config: option \"max-start\" of \"empty-lines\" should be int"
18
+ );
19
+
20
+ let err =
21
+ YamlLintConfig::from_yaml_str("rules:\n empty-lines:\n max-end: false\n")
22
+ .unwrap_err();
23
+ assert_eq!(
24
+ err,
25
+ "invalid config: option \"max-end\" of \"empty-lines\" should be int"
26
+ );
27
+ }
28
+
29
+ #[test]
30
+ fn error_on_unknown_option() {
31
+ let err =
32
+ YamlLintConfig::from_yaml_str("rules:\n empty-lines:\n unexpected: 3\n")
33
+ .unwrap_err();
34
+ assert_eq!(
35
+ err,
36
+ "invalid config: unknown option \"unexpected\" for rule \"empty-lines\""
37
+ );
38
+ }
39
+
40
+ #[test]
41
+ fn error_on_non_string_option_key() {
42
+ let err = YamlLintConfig::from_yaml_str("rules:\n empty-lines:\n 1: 2\n")
43
+ .unwrap_err();
44
+ assert_eq!(
45
+ err,
46
+ "invalid config: unknown option \"1\" for rule \"empty-lines\""
47
+ );
48
+ }
@@ -0,0 +1,35 @@
1
+ use ryl::config::YamlLintConfig;
2
+
3
+ #[test]
4
+ fn error_on_non_bool_block_mapping_option() {
5
+ let err = YamlLintConfig::from_yaml_str(
6
+ "rules:\n empty-values:\n forbid-in-block-mappings: 1\n",
7
+ )
8
+ .unwrap_err();
9
+ assert_eq!(
10
+ err,
11
+ "invalid config: option \"forbid-in-block-mappings\" of \"empty-values\" should be bool"
12
+ );
13
+ }
14
+
15
+ #[test]
16
+ fn error_on_unknown_option() {
17
+ let err = YamlLintConfig::from_yaml_str(
18
+ "rules:\n empty-values:\n unsupported: true\n",
19
+ )
20
+ .unwrap_err();
21
+ assert_eq!(
22
+ err,
23
+ "invalid config: unknown option \"unsupported\" for rule \"empty-values\""
24
+ );
25
+ }
26
+
27
+ #[test]
28
+ fn error_on_non_string_option_key() {
29
+ let err = YamlLintConfig::from_yaml_str("rules:\n empty-values:\n 1: true\n")
30
+ .unwrap_err();
31
+ assert_eq!(
32
+ err,
33
+ "invalid config: unknown option \"1\" for rule \"empty-values\""
34
+ );
35
+ }
@@ -0,0 +1,23 @@
1
+ use std::fs;
2
+
3
+ use ryl::config::{Overrides, discover_config_with_env};
4
+ use tempfile::tempdir;
5
+
6
+ #[test]
7
+ fn env_points_to_unreadable_path_errors() {
8
+ let td = tempdir().unwrap();
9
+ let dir = td.path().join("cfgdir");
10
+ fs::create_dir_all(&dir).unwrap();
11
+ let inputs = vec![dir.join("input.yaml")];
12
+ let res = discover_config_with_env(&inputs, &Overrides::default(), &|k| {
13
+ if k == "YAMLLINT_CONFIG_FILE" {
14
+ Some(dir.display().to_string())
15
+ } else {
16
+ None
17
+ }
18
+ });
19
+ assert!(
20
+ res.is_err(),
21
+ "expected error when env points to a directory, got {res:?}"
22
+ );
23
+ }
@@ -0,0 +1,15 @@
1
+ use ryl::config::{Overrides, discover_config_with_env};
2
+
3
+ #[test]
4
+ fn invalid_inline_data_errors_in_discover_config_with_env() {
5
+ let inputs: Vec<std::path::PathBuf> = vec![];
6
+ let res = discover_config_with_env(
7
+ &inputs,
8
+ &Overrides {
9
+ config_file: None,
10
+ config_data: Some("rules: {".into()),
11
+ },
12
+ &|_| None,
13
+ );
14
+ assert!(res.is_err());
15
+ }