/*
* Copyright 2012-2015 Sergey Ignatov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.erlang.build;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
import java.io.IOException;
import static org.junit.Assert.assertNotEquals;
public class ErlangBuildInSingleModuleTest extends ErlangCompilationTestBase {
public void testBuildSingleFile() throws Exception {
addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
compileAndAssertOutput(false);
}
public void testBuildWithTestSource() throws Exception {
addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
addTestFile(myModule, "test1.erl", ErlangModuleTextGenerator.module("test1").build());
compileAndAssertOutput(true);
}
public void testBuildWithParseTransform() throws Exception {
addSourceFile(myModule, "parse_transform1.erl", ErlangModuleTextGenerator.pt("parse_transform1").build());
addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").pt("parse_transform1").build());
compileAndAssertOutput(false);
}
public void testBuildWithBehaviour() throws Exception {
ErlangModuleTextGenerator.BehaviourBuilder behaviour = ErlangModuleTextGenerator.behaviour("behaviour1").callback("foo", 0);
addSourceFile(myModule, "behaviour1.erl", behaviour.build());
addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").behaviour(behaviour).build());
compileAndAssertOutput(false);
}
public void testBuildWithIncludes() throws Exception {
addSourceFile(myModule, "header.hrl", "");
addSourceFile(myModule, "module2.erl", ErlangModuleTextGenerator.module("module2").include("header.hrl").build());
myCompilationRunner.compile();
compileAndAssertOutput(false);
}
public void testBuildWithStandardLibraryInclude() throws Exception {
addSourceFile(myModule, "module2.erl", ErlangModuleTextGenerator.module("module2").includeLib("eunit/include/eunit.hrl").build());
myCompilationRunner.compile();
compileAndAssertOutput(false);
}
public void testRebuildWithNewFile() throws Exception {
VirtualFile sourceFile = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
compileAndAssertOutput(false);
long modificationTime = lastOutputModificationTime(myModule, sourceFile);
addSourceFile(myModule, "module2.erl", ErlangModuleTextGenerator.module("module2").build());
compileAndAssertOutput(false);
assertEquals(modificationTime, lastOutputModificationTime(myModule, sourceFile));
}
public void testRebuildWithoutChanges() throws Exception {
VirtualFile sourceFile1 = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
compileAndAssertOutput(false);
long lastModificationTime1 = lastOutputModificationTime(myModule, sourceFile1);
compileAndAssertOutput(false);
assertEquals(lastModificationTime1, lastOutputModificationTime(myModule, sourceFile1));
}
public void testRebuildSingleFile() throws Exception {
VirtualFile sourceFile = addSourceFile(myModule, "module2.erl", ErlangModuleTextGenerator.module("module2").build());
compileAndAssertOutput(false);
long lastModificationTime2 = lastOutputModificationTime(myModule, sourceFile);
myCompilationRunner.touch(sourceFile);
compileAndAssertOutput(false);
assertNotEquals(sourceFile.getCanonicalPath() + " wasn't rebuilt after changes in file.",
lastModificationTime2,
lastOutputModificationTime(myModule, sourceFile));
}
public void testRebuildWithModuleWithoutDependencies() throws Exception {
VirtualFile sourceFile1 = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
VirtualFile sourceFile2 = addSourceFile(myModule, "module2.erl", ErlangModuleTextGenerator.module("module2").build());
compileAndAssertOutput(false);
long lastModificationTime1 = lastOutputModificationTime(myModule, sourceFile1);
myCompilationRunner.touch(sourceFile2);
compileAndAssertOutput(false);
assertEquals(sourceFile1.getCanonicalPath() + " was rebuilt without changes. Some file in project was changed.",
lastModificationTime1,
lastOutputModificationTime(myModule, sourceFile1));
}
public void testRebuildWithParseTransform() throws Exception {
VirtualFile parseTransformSourceFile = addSourceFile(myModule, "parse_transform1.erl", ErlangModuleTextGenerator.pt("parse_transform1").build());
VirtualFile sourceFileWithDependency = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").pt("parse_transform1").build());
doTestRebuildInSingleModule(parseTransformSourceFile, sourceFileWithDependency);
}
public void testRebuildWithBehaviour() throws Exception {
ErlangModuleTextGenerator.BehaviourBuilder behaviour = ErlangModuleTextGenerator.behaviour("behaviour1").callback("foo", 0);
VirtualFile behaviourSourceFile = addSourceFile(myModule, "behaviour1.erl", behaviour.build());
VirtualFile sourceFileWithDependency = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").behaviour(behaviour).build());
doTestRebuildInSingleModule(behaviourSourceFile, sourceFileWithDependency);
}
public void testRebuildWithInclude() throws Exception {
VirtualFile headerFile = addSourceFile(myModule, "header.hrl", "");
VirtualFile sourceFileWithDependency = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").include("header.hrl").build());
doTestRebuildInSingleModule(headerFile, sourceFileWithDependency);
}
public void testRebuildWithIncludesDirectory() throws Exception {
VirtualFile includeSourceRoot = addIncludeRoot(myModule, "include");
VirtualFile headerFile = addFileToDirectory(includeSourceRoot, "header.hrl", "");
VirtualFile sourceFileWithDependency = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").include("header.hrl").build());
doTestRebuildInSingleModule(headerFile, sourceFileWithDependency);
}
public void testRebuildWithTransitiveDependencies() throws Exception {
VirtualFile headerFile = addSourceFile(myModule, "header.hrl", "");
ErlangModuleTextGenerator.BehaviourBuilder behaviour = ErlangModuleTextGenerator.behaviour("behaviour1").callback("foo", 0);
addSourceFile(myModule, "behaviour1.erl", behaviour.include("header.hrl").build());
VirtualFile sourceFileWithDependency = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").behaviour(behaviour).build());
doTestRebuildInSingleModule(headerFile, sourceFileWithDependency);
}
public void testBeamsForDeletedSourcesAreDeleted() throws Exception {
final VirtualFile erl = addSourceFile(myModule, "module1.erl", ErlangModuleTextGenerator.module("module1").build());
compileAndAssertOutput(false);
File beam = getOutputFile(myModule, erl, false);
assertNotNull(beam);
assertTrue(beam.exists());
WriteCommandAction.runWriteCommandAction(null, () -> {
try {
erl.delete(null);
}
catch (IOException e) {
throw new RuntimeException(e);
}
});
compileAndAssertOutput(false);
assertFalse(beam.exists());
}
private void doTestRebuildInSingleModule(VirtualFile dependency,
VirtualFile sourceFileWithDependency) throws Exception {
compileAndAssertOutput(false);
long sourceModificationTime = lastOutputModificationTime(myModule, sourceFileWithDependency);
myCompilationRunner.touch(dependency);
compileAndAssertOutput(false);
assertNotEquals(sourceFileWithDependency.getCanonicalPath() + " wasn't rebuilt after modification of its dependencies.",
sourceModificationTime,
lastOutputModificationTime(myModule, sourceFileWithDependency));
}
}