Package dtool.engine

Source Code of dtool.engine.ModuleParseCache_Test

/*******************************************************************************
* Copyright (c) 2014, 2014 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 dtool.engine;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;

import melnorme.lang.utils.MiscFileUtils;
import melnorme.utilbox.misc.FileUtil;
import melnorme.utilbox.misc.MiscUtil;
import melnorme.utilbox.tests.TestsWorkingDir;

import org.junit.BeforeClass;
import org.junit.Test;

import dtool.dub.BundlePath;
import dtool.dub.CommonDubTest;
import dtool.engine.ModuleParseCache;
import dtool.engine.CommonSemanticManagerTest.Tests_DToolServer;
import dtool.engine.ModuleParseCache.ParseSourceException;
import dtool.parser.DeeParserResult.ParsedModule;
import dtool.tests.CommonDToolTest;

public class ModuleParseCache_Test extends CommonDToolTest {
 
  public static final BundlePath XPTO_BUNDLE_PATH = CommonDubTest.XPTO_BUNDLE_PATH;
 
  public static final Path WORKING_DIR = TestsWorkingDir.getWorkingDir().toPath();
  public static final Path TEST_WORKING_DIR = WORKING_DIR.resolve(ModuleParseCache_Test.class.getSimpleName());
 
  protected static final Path CU_PATH = TEST_WORKING_DIR.resolve("app.d");
  protected static final String SOURCE1 = "module app; /** Source 1 */";
  protected static final String WC_SOURCE = "module app; /** WC Source */";
  protected static final String SOURCE3 = "module app; /** ModuleParse Test source3 */";

  protected ModuleParseCache mpc;
 
  @BeforeClass
  public static void setup() throws IOException {
    FileUtil.deleteDir(TEST_WORKING_DIR);
    MiscFileUtils.copyDirContentsIntoDirectory(XPTO_BUNDLE_PATH.resolve("src/"), TEST_WORKING_DIR);
  }
 
  @Test
  public void testCaching() throws Exception { testCaching$(); }
  public void testCaching$() throws Exception {
    __initModuleParseCache();
   
    basicSequence(CU_PATH);
    // repeat
    basicSequence(CU_PATH);
  }
 
  protected void __initModuleParseCache() {
    mpc = new ModuleParseCache(new Tests_DToolServer());
  }
 
  public static void writeToFileAndUpdateMTime(Path file, String contents) throws IOException {
    if(!file.toFile().exists()) {
      writeStringToFile(file, contents);
      return;
    }
    FileTime lastModifiedTime = Files.getLastModifiedTime(file);
    writeStringToFile(file, contents);
    // Make sure last modified time is different from before
    Files.setLastModifiedTime(file, FileTime.fromMillis(lastModifiedTime.toMillis() - 1_000));
  }
 
  public void updateFileContents(Path filePath, String contents) {
    updateFileContents(filePath, contents, true);
  }
 
  public void updateFileContents(Path filePath, String contents, boolean isEntryStale) {
    try {
      writeToFileAndUpdateMTime(filePath, contents);
    } catch (IOException e) {
      throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e);
    }
    assertTrue(mpc.getEntry(filePath).isStale() == isEntryStale);
  }
 
  protected void basicSequence(Path cuPath) throws ParseSourceException, IOException, FileNotFoundException {
   
    ParsedModule parsedModule = mpc.getParsedModule(CU_PATH);
    assertTrue(mpc.getParsedModule(cuPath) == parsedModule);
   
    updateFileContents(CU_PATH, SOURCE1);
    assertTrue(mpc.getEntry(CU_PATH).isStale());
    parsedModule = mpc.getParsedModule(CU_PATH);
    assertEquals(parsedModule.source, SOURCE1);
   
    // Test caching
    assertTrue(mpc.getEntry(CU_PATH).isWorkingCopy == false);
    assertTrue(mpc.getEntry(CU_PATH).isStale() == false);
    assertTrue(mpc.getParsedModule(CU_PATH) == parsedModule);
   
    // Test caching for WC
    testUpdateWorkingCopyAndParse(CU_PATH, WC_SOURCE);
   
    // Test new source update over previous working copy
    testUpdateWorkingCopyAndParse(CU_PATH, "blah");
   
    // Test file update over active working copy. Check working copy source still takes precedence
    testUpdateWorkingCopyAndParse(CU_PATH, WC_SOURCE);
    updateFileContents(CU_PATH, SOURCE3, false); // do file update
    assertTrue(mpc.getParsedModule(CU_PATH).source.equals(WC_SOURCE));
   
   
    // Test discard working copy - last update was on file
    testUpdateWorkingCopyAndParse(CU_PATH, WC_SOURCE);
    updateFileContents(CU_PATH, SOURCE3, false); // last update
    testDiscardWorkingCopy(CU_PATH, WC_SOURCE, SOURCE3);
   
    // Test discard working copy - last update was WC and file was parsed previously
    updateFileContents(CU_PATH, SOURCE3);
    mpc.getParsedModule(CU_PATH);
    testUpdateWorkingCopyAndParse(CU_PATH, WC_SOURCE); // last update
    testDiscardWorkingCopy(CU_PATH, WC_SOURCE, SOURCE3);
   
    // Test redundant discardWorkingCopy
    mpc.discardWorkingCopy(CU_PATH);
    assertTrue(mpc.getEntry(CU_PATH).isStale() == false);
   
    // Special case: first update for path is working copy, then discard
    __initModuleParseCache();
    updateFileContents(CU_PATH, SOURCE1);
    testUpdateWorkingCopyAndParse(CU_PATH, WC_SOURCE);
    testDiscardWorkingCopy(CU_PATH, WC_SOURCE, SOURCE1);
   
   
    testOptimizationsWithIdenticalSource();
   
    // Special case:
    mpc.discardWorkingCopy(CU_PATH);
    updateFileContents(CU_PATH, SOURCE1);
    parsedModule = mpc.getParsedModule(CU_PATH);
    updateFileContents(CU_PATH, SOURCE3, true);
    assertTrue(getParsedModuleIfNotStale(CU_PATH) == null);
    assertTrue(mpc.getEntry(CU_PATH).isStale());
    assertTrue(mpc.getParsedModule(CU_PATH) != parsedModule);
  }
 
  protected void testUpdateWorkingCopyAndParse(Path modulePath, String source) throws ParseSourceException {
    ParsedModule parsedModule = mpc.setWorkingCopyAndGetParsedModule(modulePath, source);
    assertTrue(mpc.getEntry(CU_PATH).isStale() == false);
    assertTrue(mpc.getParsedModule(modulePath) == parsedModule);
    assertTrue(mpc.setWorkingCopyAndGetParsedModule(modulePath, source) == parsedModule);
    assertTrue(parsedModule.source == source);
  }
 
  protected void testDiscardWorkingCopy(Path filePath, String previousSource, String expectedNewSource)
      throws ParseSourceException {
    assertTrue(mpc.getExistingParsedModule(CU_PATH).source.equals(previousSource));
    mpc.discardWorkingCopy(filePath);
    assertTrue(mpc.getEntry(filePath).isStale());
    assertTrue(mpc.getParsedModule(filePath).source.equals(expectedNewSource));
  }
 
  protected void testOptimizationsWithIdenticalSource() throws IOException, ParseSourceException {
    mpc.discardWorkingCopy(CU_PATH);
    ParsedModule parsedModule;
   
    updateFileContents(CU_PATH, WC_SOURCE);
    parsedModule = mpc.getParsedModule(CU_PATH);
    updateFileContents(CU_PATH, WC_SOURCE, true);
    testNoReparseHappened(parsedModule, CU_PATH);
   
    assertTrue(parsedModule == setWorkingCopySourceAndParse(CU_PATH, WC_SOURCE));
    testNoReparseHappened(parsedModule, CU_PATH);
   
    parsedModule = setWorkingCopySourceAndParse(CU_PATH, SOURCE3);
    updateFileContents(CU_PATH, SOURCE3, false);
    mpc.discardWorkingCopy(CU_PATH);
    testNoReparseHappened(parsedModule, CU_PATH);
  }
 
  protected void testNoReparseHappened(ParsedModule previousModule, Path filePath) throws ParseSourceException {
    assertTrue(previousModule == getParsedModuleIfNotStale(filePath));
    assertTrue(mpc.getEntry(filePath).isStale() == false);
    assertTrue(previousModule == mpc.getParsedModule(filePath));
  }
 
  protected ParsedModule getParsedModuleIfNotStale(Path path) {
    return mpc.getEntry(path).getParsedModuleIfNotStale(true);
  }
 
  protected ParsedModule setWorkingCopySourceAndParse(Path filePath, String source) {
    ParsedModule parsedModule = mpc.setWorkingCopyAndGetParsedModule(filePath, source);
    assertTrue(mpc.getEntry(filePath).isWorkingCopy);
    return parsedModule;
  }
 
  @Test
  public void testOther() throws Exception { testOther$(); }
  public void testOther$() throws Exception {
    __initModuleParseCache();
   
    Path freeformPath = MiscUtil.createValidPath("#freeFormPath");
    assertTrue(mpc.setWorkingCopyAndGetParsedModule(freeformPath, SOURCE1).source.equals(SOURCE1));
  }
 
}
TOP

Related Classes of dtool.engine.ModuleParseCache_Test

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.