1414
1515package org .eclipse .cdt .lsp .clangd .tests ;
1616
17+ import static org .junit .jupiter .api .Assertions .assertThrows ;
1718import static org .junit .jupiter .api .Assertions .assertTrue ;
1819import static org .mockito .Mockito .mock ;
1920import static org .mockito .Mockito .when ;
3233import org .eclipse .cdt .core .settings .model .ICProjectDescription ;
3334import org .eclipse .cdt .internal .core .settings .model .CConfigurationDescriptionCache ;
3435import org .eclipse .cdt .lsp .clangd .ClangdCProjectDescriptionListener ;
36+ import org .eclipse .cdt .lsp .clangd .ClangdConfigurationFileManager ;
3537import org .eclipse .cdt .lsp .clangd .MacroResolver ;
3638import org .eclipse .core .resources .IFile ;
3739import org .eclipse .core .resources .IProject ;
4648import org .junit .jupiter .api .Test ;
4749import org .junit .jupiter .api .TestInfo ;
4850import org .junit .jupiter .api .io .TempDir ;
51+ import org .yaml .snakeyaml .scanner .ScannerException ;
4952
50- final class ClangdConfigurationManagerTest {
53+ final class ClangdConfigurationFileManagerTest {
5154
52- private static final String RELATIVE_DIR_PATH_BUILD_DEFAULT = "build/ default" ;
53- private static final String RELATIVE_DIR_PATH_BUILD_DEBUG = "build/ debug" ;
55+ private static final String RELATIVE_DIR_PATH_BUILD_DEFAULT = "build" + File . separator + " default" ;
56+ private static final String RELATIVE_DIR_PATH_BUILD_DEBUG = "build" + File . separator + " debug" ;
5457 private static final String EXPANDED_CDB_SETTING = "CompileFlags: {Add: -ferror-limit=500, CompilationDatabase: %s, Compiler: g++}\n Diagnostics:\n ClangTidy: {Add: modernize*, Remove: modernize-use-trailing-return-type}\n " ;
5558 private static final String DEFAULT_CDB_SETTING = "CompileFlags: {CompilationDatabase: %s}" ;
5659 private static final String MODIFIED_DEFAULT_CDB_SETTING = DEFAULT_CDB_SETTING + "\n " ;
@@ -82,8 +85,6 @@ public void setUp(TestInfo testInfo) throws CoreException {
8285 project = TestUtils .createCProject (projectName );
8386 TestUtils .setLspPreferred (project , true );
8487 when (event .getProject ()).thenReturn (project );
85- cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEFAULT ).toPortableString ());
86- when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
8788 }
8889
8990 @ AfterEach
@@ -92,14 +93,28 @@ public void cleanUp() throws CoreException {
9293 }
9394
9495 private static File createFile (File parent , String format , String cdbDirectoryPath ) throws FileNotFoundException {
95- var file = new File (parent , ClangdCProjectDescriptionListener .CLANGD_CONFIG_FILE_NAME );
96+ return createFile (parent , ClangdCProjectDescriptionListener .CLANGD_CONFIG_FILE_NAME , format , cdbDirectoryPath );
97+ }
98+
99+ private static File createFile (File parent , String fileName , String format , String cdbDirectoryPath )
100+ throws FileNotFoundException {
101+ var file = new File (parent , fileName );
96102 try (var writer = new PrintWriter (file )) {
97103 writer .printf (format , cdbDirectoryPath );
98104 }
99105 return file ;
100106 }
101107
102- private IFile createFile (String format , String cdbDirectoryPath )
108+ /**
109+ * Creates a .clangd file in the current project
110+ * @param format
111+ * @param cdbDirectoryPath
112+ * @return
113+ * @throws UnsupportedEncodingException
114+ * @throws IOException
115+ * @throws CoreException
116+ */
117+ private IFile createConfigFile (String format , String cdbDirectoryPath )
103118 throws UnsupportedEncodingException , IOException , CoreException {
104119 var file = project .getFile (ClangdCProjectDescriptionListener .CLANGD_CONFIG_FILE_NAME );
105120 try (final var data = new ByteArrayInputStream (
@@ -126,11 +141,12 @@ void testCreateClangdConfigFileInProject() throws IOException, CoreException {
126141 var configFile = new File (projectDir , ClangdCProjectDescriptionListener .CLANGD_CONFIG_FILE_NAME );
127142 var refFile = createFile (TEMP_DIR , DEFAULT_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEFAULT );
128143 // The current working directory of the builder in the project is set to RELATIVE_DIR_PATH_BUILD_DEFAULT:
129- //cwdBuilder = new Path(project.getLocation().append(RELATIVE_DIR_PATH_BUILD_DEFAULT).toPortableString());
144+ cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEFAULT ).toPortableString ());
145+ when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
130146
131147 // GIVEN a project without .clangd project configuration file:
132148 assertTrue (configFile .length () == 0 );
133- // WHEN the ClangdConfigurationManager.setCompilationDatabase method gets called:
149+ // WHEN the ClangdConfigurationManager.handleEvent method gets called:
134150 clangdConfigurationManager .handleEvent (event , macroResolver );
135151 // THEN a new file has been created in the project:
136152 assertTrue (configFile .length () > 0 );
@@ -151,12 +167,13 @@ void testCreateClangdConfigFileInProject() throws IOException, CoreException {
151167 void testEmptyClangdConfigFileInProject () throws IOException , CoreException {
152168 var refFile = createFile (TEMP_DIR , DEFAULT_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEFAULT );
153169 // The current working directory of the builder in the project is set to RELATIVE_DIR_PATH_BUILD_DEFAULT:
154- //cwdBuilder = new Path(project.getLocation().append(RELATIVE_DIR_PATH_BUILD_DEFAULT).toPortableString());
170+ cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEFAULT ).toPortableString ());
171+ when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
155172
156173 // GIVEN an existing but empty .clangd configuration file in the project:
157- var emptyConfigFile = createFile ("%s" , " " );
158- // WHEN the ClangdConfigurationManager.setCompilationDatabase method gets called with a new cdb path "build/debug":
159- // clangdConfigurationManager.handleEvent(event, macroResolver);
174+ var emptyConfigFile = createConfigFile ("%s" , " " );
175+ // WHEN the ClangdConfigurationManager.handleEvent method gets called with a new cdb path "build/debug":
176+ clangdConfigurationManager .handleEvent (event , macroResolver );
160177 // THEN the updated file matches the expected content with the given CompilationDatabase directory "build/debug":
161178 assertTrue (Arrays .equals (Files .readAllBytes (emptyConfigFile .getLocation ().toFile ().toPath ()),
162179 Files .readAllBytes (refFile .toPath ())));
@@ -175,29 +192,35 @@ void testEmptyClangdConfigFileInProject() throws IOException, CoreException {
175192 void testUpdateClangdConfigFileInProject () throws IOException , CoreException {
176193 var projectDir = project .getLocation ().toPortableString ();
177194 var configFile = new File (projectDir , ClangdCProjectDescriptionListener .CLANGD_CONFIG_FILE_NAME );
178- var cwdDefault = createFile (TEMP_DIR , MODIFIED_DEFAULT_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEFAULT );
179- var cwdDebug = createFile (TEMP_DIR , MODIFIED_DEFAULT_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEBUG );
195+ var refFileDefault = createFile (TEMP_DIR , ".clangdDefault" , DEFAULT_CDB_SETTING ,
196+ RELATIVE_DIR_PATH_BUILD_DEFAULT );
197+ // Use MODIFIED_DEFAULT_CDB_SETTING here, because the org.yaml.snakeyaml.Yaml.dump appends a '\n' at the last line:
198+ var refFileDebug = createFile (TEMP_DIR , ".clangdDebug" , MODIFIED_DEFAULT_CDB_SETTING ,
199+ RELATIVE_DIR_PATH_BUILD_DEBUG );
180200 // The current working directory of the builder in the project is set to RELATIVE_DIR_PATH_BUILD_DEFAULT:
181- //cwdBuilder = new Path(project.getLocation().append(RELATIVE_DIR_PATH_BUILD_DEFAULT).toPortableString());
201+ cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEFAULT ).toPortableString ());
202+ when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
182203
183204 // GIVEN a project without .clangd project configuration file:
184205 assertTrue (configFile .length () == 0 );
185206 // AND the ClangdConfigurationManager.handleEvent method gets called:
186207 clangdConfigurationManager .handleEvent (event , macroResolver );
187208 // THEN a new file has been created in the project:
188209 assertTrue (configFile .length () > 0 );
189- // THEN the file matches the expected content:
190- //assertTrue(Arrays.equals(Files.readAllBytes(configFile.toPath()), Files.readAllBytes(cwdDefault.toPath())));
191- // WHEN the active build configuration changes and the CWD is set to RELATIVE_DIR_PATH_BUILD_DEBUG:
192- //cwdBuilder = new Path(project.getLocation().append(RELATIVE_DIR_PATH_BUILD_DEBUG).toPortableString());
210+ // THEN the created file matches the expected content:
211+ assertTrue (Arrays .equals (Files .readAllBytes (configFile .toPath ()), Files .readAllBytes (refFileDefault .toPath ())));
212+
213+ // WHEN the CWD in the build configuration changes to build/debug:
214+ cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEBUG ).toPortableString ());
215+ when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
193216 // AND the handleEvent gets called again:
194217 clangdConfigurationManager .handleEvent (event , macroResolver );
195218 // THEN the updated file matches the expected content:
196- assertTrue (Arrays .equals (Files .readAllBytes (configFile .toPath ()), Files .readAllBytes (cwdDebug .toPath ())));
219+ assertTrue (Arrays .equals (Files .readAllBytes (configFile .toPath ()), Files .readAllBytes (refFileDebug .toPath ())));
197220
198221 //clean up:
199- cwdDefault .delete ();
200- cwdDebug .delete ();
222+ refFileDefault .delete ();
223+ refFileDebug .delete ();
201224 }
202225
203226 /**
@@ -211,9 +234,10 @@ void testUpdateExpandedClangdConfigFileInProject() throws IOException, CoreExcep
211234 var refFile = createFile (TEMP_DIR , EXPANDED_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEBUG );
212235
213236 // GIVEN an existing expanded .clangd configuration file in the project pointing to "build/default":
214- var configFile = createFile (EXPANDED_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEFAULT );
237+ var configFile = createConfigFile (EXPANDED_CDB_SETTING , RELATIVE_DIR_PATH_BUILD_DEFAULT );
215238 // WHEN the ClangdConfigurationManager.handleEvent method gets called and the builder CWD points to "build/debug":
216- //cwdBuilder = new Path(project.getLocation().append(RELATIVE_DIR_PATH_BUILD_DEBUG).toPortableString());
239+ cwdBuilder = new Path (project .getLocation ().append (RELATIVE_DIR_PATH_BUILD_DEBUG ).toPortableString ());
240+ when (setting .getBuilderCWD ()).thenReturn (cwdBuilder );
217241 clangdConfigurationManager .handleEvent (event , macroResolver );
218242 // THEN the updated file matches the expected content:
219243 assertTrue (Arrays .equals (Files .readAllBytes (configFile .getLocation ().toFile ().toPath ()),
@@ -229,15 +253,16 @@ void testUpdateExpandedClangdConfigFileInProject() throws IOException, CoreExcep
229253 * @throws IOException
230254 * @throws CoreException
231255 */
232- // @Test
233- // void testInvalidYamlSyntax() throws IOException, CoreException {
234- // // GIVEN an existing .clangd configuration file with invalid yaml syntax (contains tab):
235- // createFile(INVALID_YAML_SYNTAX_CONTAINS_TAB, RELATIVE_DIR_PATH_BUILD_DEFAULT);
236- // // WHEN the ClangdConfigurationManager.setCompilationDatabase method gets called with a new cdb path "build/debug":
237- // // THEN a ScannerExcpetion is expected:
238- // assertThrows(ScannerException.class, () -> {
239- // clangdConfigurationManager.handleEvent(event, macroResolver);//RELATIVE_DIR_PATH_BUILD_DEBUG);
240- // });
241- // }
256+ @ Test
257+ void testInvalidYamlSyntax () throws IOException , CoreException {
258+ // GIVEN an existing .clangd configuration file with invalid yaml syntax (contains tab):
259+ createConfigFile (INVALID_YAML_SYNTAX_CONTAINS_TAB , RELATIVE_DIR_PATH_BUILD_DEFAULT );
260+ // WHEN the ClangdConfigurationManager.setCompilationDatabasePath method gets called with a new cdb path "build/debug":
261+ // THEN a ScannerExcpetion is expected:
262+ assertThrows (ScannerException .class , () -> {
263+ ((ClangdConfigurationFileManager ) clangdConfigurationManager ).setCompilationDatabase (project ,
264+ RELATIVE_DIR_PATH_BUILD_DEBUG );
265+ });
266+ }
242267
243268}
0 commit comments