Skip to content

Commit

Permalink
Add forbid-in-block-sequences option
Browse files Browse the repository at this point in the history
  • Loading branch information
sbaudoin committed Nov 9, 2023
1 parent 8b57857 commit ab3a9ac
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 20 deletions.
49 changes: 45 additions & 4 deletions src/main/java/com/github/sbaudoin/yamllint/rules/EmptyValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@
* <ul>
* <li>Use {@code forbid-in-block-mappings} to prevent empty values in block mappings.</li>
* <li>Use {@code forbid-in-flow-mappings} to prevent empty values in flow mappings.</li>
* <li>Use {@code forbid-in-block-sequences} to prevent empty values in block sequences.</li>
* </ul>
*
* <p>Default values (when enabled):</p>
* <pre>
* rules:
* empty-values:
* forbid-in-block-mappings: true
* forbid-in-flow-mappings: true
* forbid-in-block-sequences: true
* </pre>
*
* <p>Examples:</p>
* <p>With <code>empty-values: {forbid-in-block-mappings: true}</code>
* the following code snippets would **PASS**:
Expand Down Expand Up @@ -58,15 +68,38 @@
* the following code snippets would **FAIL**:
* <pre>{prop: }</pre>
* <pre> {a: 1, b:, c: 3}</pre>
*
* <p>With <code>empty-values: {forbid-in-block-sequences: true}</code>
* the following code snippet would **PASS**:
* <pre>
* some-sequence:
* - string item
* </pre>
* <pre>
* some-sequence:
* - null
* </pre>
* the following code snippets would **FAIL**:
* <pre>
* some-sequence:
* -
* </pre>
* <pre>
* some-sequence:
* - string item
* -
* </pre>
*/
public class EmptyValues extends TokenRule {
public static final String OPTION_FORBID_IN_BLOCK_MAPPINGS = "forbid-in-block-mappings";
public static final String OPTION_FORBID_IN_FLOW_MAPPINGS = "forbid-in-flow-mappings";
public static final String OPTION_FORBID_IN_BLOCK_MAPPINGS = "forbid-in-block-mappings";
public static final String OPTION_FORBID_IN_FLOW_MAPPINGS = "forbid-in-flow-mappings";
public static final String OPTION_FORBID_IN_BLOCK_SEQUENCES = "forbid-in-block-sequences";


public EmptyValues() {
registerOption(OPTION_FORBID_IN_BLOCK_MAPPINGS, false);
registerOption(OPTION_FORBID_IN_FLOW_MAPPINGS, false);
registerOption(OPTION_FORBID_IN_BLOCK_MAPPINGS, true);
registerOption(OPTION_FORBID_IN_FLOW_MAPPINGS, true);
registerOption(OPTION_FORBID_IN_BLOCK_SEQUENCES, true);
}

@Override
Expand All @@ -89,6 +122,14 @@ public List<LintProblem> check(Map<Object, Object> conf, Token token, Token prev
}
}

if ((boolean)conf.get(OPTION_FORBID_IN_BLOCK_SEQUENCES)) {
if (token instanceof BlockEntryToken && (next instanceof KeyToken || next instanceof BlockEndToken || next instanceof BlockEntryToken)) {
problems.add(new LintProblem(token.getStartMark().getLine() + 1,
token.getEndMark().getColumn() + 1,
"empty value in block sequence"));
}
}

return problems;
}
}
148 changes: 132 additions & 16 deletions src/test/java/com/github/sbaudoin/yamllint/rules/EmptyValuesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ void testDisabled() throws YamlLintConfigException {
@Test
void testInBlockMappingsDisabled() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n", conf);
check("---\n" +
Expand All @@ -57,7 +58,8 @@ void testInBlockMappingsDisabled() throws YamlLintConfigException {
@Test
void testInBlockMappingsSingleLine() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"implicitly-null:\n", conf, getLintProblem(2, 17));
check("---\n" +
Expand All @@ -71,7 +73,8 @@ void testInBlockMappingsSingleLine() throws YamlLintConfigException {
@Test
void testInBlockMappingsAllLines() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
"bar:\n" +
Expand All @@ -84,7 +87,8 @@ void testInBlockMappingsAllLines() throws YamlLintConfigException {
@Test
void testInBlockMappingsExplicitEndOfDocument() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
"...\n", conf, getLintProblem(2, 5));
Expand All @@ -93,7 +97,8 @@ void testInBlockMappingsExplicitEndOfDocument() throws YamlLintConfigException {
@Test
void testInBlockMappingsNotEndOfDocument() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
"bar:\n" +
Expand All @@ -103,7 +108,8 @@ void testInBlockMappingsNotEndOfDocument() throws YamlLintConfigException {
@Test
void testInBlockMappingsDifferentLevel() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
" bar:\n" +
Expand All @@ -113,7 +119,8 @@ void testInBlockMappingsDifferentLevel() throws YamlLintConfigException {
@Test
void testInBlockMappingsEmptyFlowMapping() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}",
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable");
check("---\n" +
Expand All @@ -127,7 +134,8 @@ void testInBlockMappingsEmptyFlowMapping() throws YamlLintConfigException {
@Test
void testInBlockMappingsEmptyBlockSequence() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
" -\n", conf);
Expand All @@ -136,7 +144,8 @@ void testInBlockMappingsEmptyBlockSequence() throws YamlLintConfigException {
@Test
void testInBlockMappingsNotEmptyOrExplicitNull() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
" bar:\n" +
Expand All @@ -161,7 +170,8 @@ void testInBlockMappingsNotEmptyOrExplicitNull() throws YamlLintConfigException
@Test
void testInBlockMappingsVariousExplicitNull() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}");
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}");
check("---\n" +
"null-alias: ~\n", conf);
check("---\n" +
Expand All @@ -173,7 +183,8 @@ void testInBlockMappingsVariousExplicitNull() throws YamlLintConfigException {
@Test
void testInBlockMappingsComments() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: true,",
" forbid-in-flow-mappings: false}",
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}",
"comments: disable");
check("---\n" +
"empty: # comment\n" +
Expand All @@ -186,7 +197,8 @@ void testInBlockMappingsComments() throws YamlLintConfigException {
@Test
void testInFlowMappingsDisabled() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: false}",
" forbid-in-flow-mappings: false," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable");
check("---\n" +
Expand All @@ -205,7 +217,8 @@ void testInFlowMappingsDisabled() throws YamlLintConfigException {
@Test
void testInFlowMappingsSingleLine() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: true}",
" forbid-in-flow-mappings: true," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable");
check("---\n" +
Expand Down Expand Up @@ -233,7 +246,8 @@ void testInFlowMappingsSingleLine() throws YamlLintConfigException {
@Test
void testInFlowMappingsMultiLine() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: true}",
" forbid-in-flow-mappings: true," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable");
check("---\n" +
Expand All @@ -260,7 +274,8 @@ void testInFlowMappingsMultiLine() throws YamlLintConfigException {
@Test
void testInFlowMappingsVariousExplicitNull() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: true}",
" forbid-in-flow-mappings: true," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable");
check("---\n" +
Expand All @@ -276,7 +291,8 @@ void testInFlowMappingsVariousExplicitNull() throws YamlLintConfigException {
@Test
void testInFlowMappingsComments() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,",
" forbid-in-flow-mappings: true}",
" forbid-in-flow-mappings: true," +
" forbid-in-block-sequences: false}",
"braces: disable",
"commas: disable",
"comments: disable");
Expand All @@ -295,4 +311,104 @@ void testInFlowMappingsComments() throws YamlLintConfigException {
getLintProblem(7, 9),
getLintProblem(10, 5));
}

@Test
void testInBlockSequencesDisabled() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false," +
" forbid-in-flow-mappings: false,\n" +
" forbid-in-block-sequences: false}");
check("---\n" +
"foo:\n" +
" - bar\n" +
" -\n", conf);
check("---\n" +
"foo:\n" +
" -\n", conf);
}

@Test
void testInBlockSequencesPrimativeItem() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,\n" +
" forbid-in-flow-mappings: false,\n" +
" forbid-in-block-sequences: true}");
check("---\n" +
"foo:\n" +
" -\n", conf,
getLintProblem(3, 4));
check("---\n" +
"foo:\n" +
" - bar\n" +
" -\n", conf,
getLintProblem(4, 4));
check("---\n" +
"foo:\n" +
" - 1\n" +
" - 2\n" +
" -\n", conf,
getLintProblem(5, 4));
check("---\n" +
"foo:\n" +
" - true\n", conf);
}

@Test
void test_in_block_sequences_complex_objects() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,\n" +
" forbid-in-flow-mappings: false,\n" +
" forbid-in-block-sequences: true}");
check("---\n" +
"foo:\n" +
" - a: 1\n", conf);
check("---\n" +
"foo:\n" +
" - a: 1\n" +
" -\n", conf,
getLintProblem(4, 4));
check("---\n" +
"foo:\n" +
" - a: 1\n" +
" b: 2\n" +
" -\n", conf,
getLintProblem(5, 4));
check("---\n" +
"foo:\n" +
" - a: 1\n" +
" - b: 2\n" +
" -\n", conf,
getLintProblem(5, 4));
check("---\n" +
"foo:\n" +
" - - a\n" +
" - b: 2\n" +
" -\n", conf,
getLintProblem(5, 6));
check("---\n" +
"foo:\n" +
" - - a\n" +
" - b: 2\n" +
" -\n", conf,
getLintProblem(5, 4));
}

@Test
void testInBlockSequencesVariousExplicitNull() throws YamlLintConfigException {
YamlLintConfig conf = getConfig("empty-values: {forbid-in-block-mappings: false,\n" +
" forbid-in-flow-mappings: false,\n" +
" forbid-in-block-sequences: true}");
check("---\n" +
"foo:\n" +
" - null\n", conf);
check("---\n" +
"- null\n", conf);
check("---\n" +
"foo:\n" +
" - bar: null\n" +
" - null\n", conf);
check("---\n" +
"- null\n" +
"- null\n", conf);
check("---\n" +
"- - null\n" +
" - null\n", conf);
}
}

0 comments on commit ab3a9ac

Please sign in to comment.