3535import java .nio .charset .StandardCharsets ;
3636import java .nio .file .Files ;
3737import java .nio .file .Path ;
38+ import java .nio .file .Paths ;
3839import java .util .ArrayList ;
3940import java .util .Arrays ;
4041import java .util .Collections ;
@@ -108,6 +109,57 @@ void testWriteBasicFile(final @TempDir Path tempDir) throws IOException {
108109 assertContentsSame (this .resource ("write-expected.yml" ), target );
109110 }
110111
112+ @ Test
113+ void testNonExistentFile () throws IOException {
114+ final Path path = Paths .get ("non-existent-file.yml" );
115+ final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ().path (path ).build ();
116+
117+ final ConfigurationNode actual = loader .load ();
118+ assertEquals (CommentedConfigurationNode .root (), actual );
119+ }
120+
121+ @ Test
122+ void testEmptyFile (final @ TempDir Path tempDir ) throws IOException {
123+ // an empty file should be seen as empty node, by default SnakeYaml returns null for loading an empty file.
124+ // Check if it correctly gets mapped to an empty node.
125+
126+ // Configurate's Spotless settings require an empty row after the last row (so essentially making the file
127+ // multiline), to bypass this we write an empty temp file and read that.
128+ final Path emptyFile = tempDir .resolve ("empty-file.yml" );
129+ Files .write (emptyFile , Collections .emptyList ());
130+
131+ final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ().path (emptyFile ).build ();
132+
133+ final ConfigurationNode actual = loader .load ();
134+ assertEquals (CommentedConfigurationNode .root (), actual );
135+ }
136+
137+ @ Test
138+ void testEmptyFileMultiline () throws IOException {
139+ // a multiline file has at least some data (the fact that it has multiple lines), which is why it's handled
140+ // differently inside SnakeYaml. This is seen as a mapping node with the Tag COMMENT.
141+
142+ final URL url = this .resource ("no-data-multiline.yml" );
143+ final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ().url (url ).build ();
144+
145+ final ConfigurationNode actual = loader .load ();
146+ assertEquals (CommentedConfigurationNode .root (), actual );
147+ }
148+
149+ @ Test
150+ void testEmptyFileOnlyComments () throws IOException {
151+ // just like 'empty file' and 'empty file multiline', this is kind of a weird situation.
152+ // In SnakeYaml, when the file exists of just comments, the first event will be StreamEnd.
153+ // getSingleNode will return null, getSingleData uses the Constructor of Tag Null, which just returns null.
154+ // Make sure that we return an empty node there.
155+
156+ final URL url = this .resource ("no-data-just-comments.yml" );
157+ final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ().url (url ).build ();
158+
159+ final ConfigurationNode actual = loader .load ();
160+ assertEquals (CommentedConfigurationNode .root (), actual );
161+ }
162+
111163 @ Test
112164 void testReadComments () throws IOException {
113165 final ConfigurationNode expected = CommentedConfigurationNode .root (n ->
@@ -123,8 +175,7 @@ void testReadComments() throws IOException {
123175 ));
124176
125177 final URL url = this .resource ("comments-test.yml" );
126- final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ()
127- .url (url ).build ();
178+ final YamlConfigurationLoader loader = YamlConfigurationLoader .builder ().url (url ).build ();
128179
129180 final ConfigurationNode actual = loader .load ();
130181 assertEquals (expected , actual );
0 commit comments