/******************************************************************************* * Copyright (c) 2015 Bruno Medeiros and other Contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package mmrnmhrm.core.dub_model; import static dtool.dub.CommonDubTest.ERROR_DUB_RETURNED_NON_ZERO; import static dtool.dub.CommonDubTest.bundle; import static dtool.dub.CommonDubTest.main; import static dtool.dub.CommonDubTest.paths; import static dtool.dub.CommonDubTest.rawDeps; import static dtool.dub.DubBundle.DEFAULT_VERSION; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import org.eclipse.core.resources.IProject; import org.junit.Test; import dtool.dub.CommonDubTest.DubBundleChecker; import dtool.dub.DubBundle; import dtool.dub.DubBundleDescription; import dtool.dub.DubManifestParser; import dtool.dub.DubManifestParserTest; import dtool.tests.CommonDToolTest; import melnorme.utilbox.concurrency.LatchRunnable; import melnorme.utilbox.misc.Location; public class DeeBundleModelManagerTest extends AbstractDeeModelManagerTest { public static final String DUB_TEST = "DubTest"; public static final String DUB_LIB = "DubLib"; public static final Location DUB_TEST_BUNDLES = DubManifestParserTest.DUB_TEST_BUNDLES; protected static final DubBundleChecker FOO_LIB_BUNDLE = bundle(DUB_TEST_BUNDLES.resolve_fromValid("foo_lib"), null, "foo_lib", DEFAULT_VERSION, paths("src", "src2")); protected static final DubBundleChecker BAR_LIB_BUNDLE = bundle(DUB_TEST_BUNDLES.resolve_fromValid("bar_lib"), null, "bar_lib", DEFAULT_VERSION, paths("source")); @Test public void testBasic() throws Exception { testBasic$(); } public void testBasic$() throws Exception { deleteProject(DUB_TEST); // In case drop-to-frame is used during debugging. _awaitModelUpdates_(); assertTrue(model.getBundleInfo(project(DUB_TEST)) == null); IProject project; long taskCount; // Test project with dub.json, but no D nature LatchRunnable latchRunnable = new LatchRunnable(); getModelAgent().submitBasicRunnable(latchRunnable); taskCount = getModelAgent().getSubmittedTaskCount(); project = createAndOpenProject(DUB_TEST, true).getProject(); writeDubJson(project, jsObject(jsEntry("name", "xptobundle"))); // check no changes or updates submitted: assertTrue(getModelAgent().getSubmittedTaskCount() == taskCount); assertTrue(model.getBundleInfo(project) == null); latchRunnable.releaseAll(); // Ensure non-d projects dont provoke updates deleteProject(DUB_TEST); assertTrue(getModelAgent().getSubmittedTaskCount() == taskCount); // Test project with D nature, but no dub.json taskCount = getModelAgent().getSubmittedTaskCount(); project = createAndOpenDeeProject(DUB_TEST, true); // There should be an error bundle info assertTrue(model.getBundleInfo(project).hasErrors()); // Test concurrency: updating a project that was removed in the meantime LatchRunnable preUpdateLatch = writeDubJsonWithModelLatch(project, "{"+ jsEntry("name", "xptobundle")+ jsFileEnd()); DubBundleDescription unresolvedBundleDesc = getExistingDubBundleInfo(project); assertTrue(model.getBundleInfo(project) != null); project.delete(true, null); preUpdateLatch.releaseAll(); _awaitModelUpdates_(); assertTrue(model.getBundleInfo(project) == null); _awaitModelUpdates_(); // Run sequence of workspace model tests project = createAndOpenDeeProject(DUB_TEST, true); runBasicTestSequence______________(project); project.delete(true, null); // cleanup assertTrue(model.getBundleInfo(project) == null); // Verify code path where a non-D project that already has dub manifest is made a D project. _awaitModelUpdates_(); project = createAndOpenProject(DUB_TEST, true); LatchRunnable modelLatch = writeDubJsonWithModelLatch(project, jsObject(jsEntry("name", "xptobundle"))); setupStandardDeeProject(project); System.out.println("--------- .project contents: "); System.out.println(readFileContents(project.getFile(".project"))); unresolvedBundleDesc = getExistingDubBundleInfo(project); modelLatch.releaseAll(); checkDubModel(unresolvedBundleDesc, project, main(loc(project), null, "xptobundle", DubBundle.DEFAULT_VERSION, srcFolders(), rawDeps())); testProjectBPDependencies(); } public void runBasicTestSequence______________(IProject project) throws Exception { Location location = loc(project); writeDubJsonAndCheckDubModel("{"+ jsEntry("name", "xptobundle")+ jsFileEnd(), project, main(location, null, "xptobundle", DEFAULT_VERSION, srcFolders(), rawDeps())); createFolder(project.getFolder("src")); createFolder(project.getFolder("src-test")); createFolder(project.getFolder("src-import")); writeDubJsonAndCheckDubModel("{"+ jsEntry("name", "xptobundle")+ jsEntry("importPaths", jsArray("src", "src-test"))+ jsEntry("version", "2.1.0")+ jsFileEnd(), project, main(location, null, "xptobundle", "2.1.0", srcFolders("src", "src-test"), rawDeps()) ); writeDubJsonAndCheckDubModel( readStringFromFile(DUB_TEST_BUNDLES.resolve_fromValid("XptoBundle/dub.json")), project, main(location, null, "xptobundle", DEFAULT_VERSION, srcFolders("src", "src-test", "src-import"), rawDeps("foo_lib"), FOO_LIB_BUNDLE, BAR_LIB_BUNDLE ) ); writeDubJsonAndCheckDubModel("{"+ jsEntry("nameMISSING", "xptobundle")+ jsFileEnd(), project, bundle(DubManifestParser.ERROR_BUNDLE_NAME_UNDEFINED, CommonDToolTest.IGNORE_STR)); writeDubJsonAndCheckDubModel("{"+ jsEntry("name", "xptobundle")+ jsFileEnd(), project, main(location, null, "xptobundle", DEFAULT_VERSION, srcFolders("src"), rawDeps())); // Test errors occurring from running dub describe writeDubJsonAndCheckDubModel( readStringFromFile(DUB_TEST_BUNDLES.resolve_fromValid("ErrorBundle_MissingDep/dub.json")), project, main(location, ERROR_DUB_RETURNED_NON_ZERO, "error_bundle_missing_dep", DEFAULT_VERSION, srcFolders("src"), rawDeps("foo_lib", "NonExistantDep"), FOO_LIB_BUNDLE, bundle("" , "NonExistantDep") ) ); } public void testProjectBPDependencies() throws Exception { IProject project = createAndOpenDeeProject(DUB_TEST, true); String dubTestJson = jsObject(jsEntry("name", "dub_test"), jsEntryValue("dependencies", "{ \"dub_lib\": \"~master\"}")); writeDubJson(project, dubTestJson); IProject libProject = createAndOpenProject(DUB_LIB, true).getProject(); Location libProjectLocation = loc(libProject); String dubLibJson = jsObject(jsEntry("name", "dub_lib")); writeDubJson(libProject, dubLibJson); // DUB_LIB project buildpath entry not on DUB_TEST yet _awaitModelUpdates_(); // There used to be a bug here, // but I believe it has been fixed since DLTK lib buildpath usage was removed DubBundleDescription dubBundle = getExistingDubBundleInfo(project); checkFullyResolvedCode(project, dubBundle, main(loc(project), null, "dub_test", DEFAULT_VERSION, srcFolders(), rawDeps("dub_lib"), bundle(libProjectLocation, "dub_lib") )); setupStandardDeeProject(libProject); _awaitModelUpdates_(); // Check project buildpath entry has been added checkFullyResolvedCode(project, dubBundle, main(loc(project), null, "dub_test", DEFAULT_VERSION, srcFolders(), rawDeps("dub_lib"), new DubBundleChecker(loc(libProject), "dub_lib") )); libProject.delete(true, null); _awaitModelUpdates_(); // Check project buildpath entry has been removed checkFullyResolvedCode(project, dubBundle, main(loc(project), null, "dub_test", DEFAULT_VERSION, srcFolders(), rawDeps("dub_lib"), bundle(libProjectLocation, "dub_lib") )); } }