updater tests and test data moved to 'updater' module
authornik <Nikolay.Chashnikov@jetbrains.com>
Tue, 4 Feb 2014 15:23:34 +0000 (19:23 +0400)
committernik <Nikolay.Chashnikov@jetbrains.com>
Wed, 5 Feb 2014 08:00:56 +0000 (12:00 +0400)
19 files changed:
updater/testData/Readme.txt [new file with mode: 0644]
updater/testData/bin/focuskiller.dll [new file with mode: 0644]
updater/testData/bin/idea.bat [new file with mode: 0644]
updater/testData/bin/idea.properties [new file with mode: 0644]
updater/testData/lib/annotations.jar [new file with mode: 0644]
updater/testData/lib/annotations_changed.jar [new file with mode: 0644]
updater/testData/lib/boot.jar [new file with mode: 0644]
updater/testData/lib/boot2.jar [new file with mode: 0644]
updater/testData/lib/boot2_changed_with_unchanged_content.jar [new file with mode: 0644]
updater/testData/lib/boot_with_directory_becomes_file.jar [new file with mode: 0644]
updater/testData/lib/bootstrap.jar [new file with mode: 0644]
updater/testData/lib/bootstrap_deleted.jar [new file with mode: 0644]
updater/testSrc/com/intellij/updater/DigesterTest.java [new file with mode: 0644]
updater/testSrc/com/intellij/updater/PatchFileCreatorTest.java [new file with mode: 0644]
updater/testSrc/com/intellij/updater/PatchTest.java [new file with mode: 0644]
updater/testSrc/com/intellij/updater/PatchTestCase.java [new file with mode: 0644]
updater/testSrc/com/intellij/updater/RunnerTest.java [new file with mode: 0644]
updater/testSrc/com/intellij/updater/UpdaterTestCase.java [new file with mode: 0644]
updater/updater.iml

diff --git a/updater/testData/Readme.txt b/updater/testData/Readme.txt
new file mode 100644 (file)
index 0000000..c509af0
--- /dev/null
@@ -0,0 +1,166 @@
+IntelliJ IDEA 8.0M1 - README
+
+Thank you for downloading IntelliJ IDEA!
+
+IntelliJ IDEA is a multi-platform Java IDE, which includes intelligent editor, rich-featured GUI designer,
+visual debugger, javac/jikes/rmic compiler integration, refactoring, enhanced project navigation,
+intelligent code inspection and analysis features, J2EE and JDK 1.5 support.
+
+
+Contents:
+=========
+  BUILD.TXT           File containing the current build number
+  KnownIssues.TXT     Known issues and workarounds
+  README.TXT          This file
+  bin/                Startup scripts for launching IntelliJ IDEA
+  help/               Online help files
+  jre/                Bundled JRE
+  lib/                Library files
+  license/            License files for IntelliJ IDEA and bundled software
+  plugins/            Standard plugins
+  redist/             Contains libraries that need to be redistributed with your application if certain IDEA features are used:
+                      - forms_rt.jar should be distributed with your applications that use GUI forms with
+                        the "GridLayoutManager (IntelliJ)" layout manager
+                      - javac2.jar is an Ant task for building applications that use IntelliJ IDEA's UI Designer
+                        bytecode generation or @NotNull assertions generation
+                      - annotations.jar contains JDK 1.5 annotation classes for 'Constant Conditions & Exceptions' inspection tool.
+
+  Install-Linux-tar.txt     Installation instructions for Linux (included in Linux installation package only)
+  Install-Windows-zip.txt   Installation instructions for Windows zip-file  (included in Windows zip installation package only)
+
+  USER_HOME/.IntelliJIdea80/
+
+      config/         Configuration files (See INSTALLATION_HOME/bin/idea.properties to tweak location of the configs)
+        codestyles/       User's code style settings
+        colors/           User's colors and fonts settings
+        fileTemplates/    Custom file templates
+        filetypes/        Custom file types
+        ideTalk/          ideTalk settings
+        inspection/       Executable file and auxiliary data for running offline code inspections
+        keymaps/          Contains files with custom keymaps
+        migration/        API migration map
+        options/          IDE options configuration files
+        plugins/          Directory for custom plugins (it appears after the 1st plugin is installed)
+        shelf/            Shelved changes (in standard .patch file format)
+        templates/        Live templates, both built-in and custom
+        tools/            External tools
+        idea70.key        File containing your license key (editing not recommended)
+
+      system/         Various IDEA internal caches including Local History data storage.
+                      (See INSTALLATION_HOME/bin/idea.properties to tweak location of the caches).
+                      Also log directory with IDEA log files is located there.
+
+
+Installing IntelliJ IDEA
+========================
+  For Linux and other Generic Unix users:
+  Please read the contents of the Install-Linux-tar.txt file.
+
+  Installing on Mac OS:
+  IntelliJ IDEA is distributed as a .dmg file. You only need to drag it to
+  the destination folder, from which you can start the application.
+
+Uninstalling IntelliJ IDEA
+==========================
+  If you installed IntelliJ IDEA with the help of Installation Wizard, then
+  just run the INSTALLATION_HOME/bin/Uninstall.exe file
+
+  To uninstall IntelliJ IDEA after manual installation, simply delete the
+  contents of the IntelliJ IDEA home installation directory.
+
+
+Licensing & pricing
+==========================
+  Licensing and pricing information can be found at http://www.jetbrains.com/idea/buy/index.html.
+
+
+IntelliJ IDEA Overview
+==========================
+  For general info and facts on IntelliJ IDEA, you can refer to IntelliJ IDEA Info Kit at
+  http://www.jetbrains.com/idea/documentation/product_info_kit.html.
+
+
+IDEA Development Package
+==========================
+  Contains:
+  - Source code for the OpenAPI classes;
+  - Documentation (JavaDocs for the OpenAPI and a number of additional components);
+  - Simple example plugins demonstrating usage of the OpenAPI;
+  - Source code for plugins shipped with IDEA:
+      * Plugin Development Kit
+      * IDEtalk plugin
+      * Images support plugin
+      * Inspection Gadgets
+      * Intention PowerPack
+      * J2ME development support plugin
+      * JavaScript support plugin
+      * JavaScript inspections plugin
+      * JavaScript Intention PowerPack
+      * GWTStudio plugin
+      * KlassMaster stacktrace unscramble plugin
+      * StrutsAssistant plugin
+      * StarTeam, Perforce, Subversion, Visual SourceSafe integration
+      * Tomcat, Weblogic, WebSphere, Geronimo, JBoss, GlassFish, JSR45 integration
+
+  Download page: http://www.jetbrains.com/idea/download/index.html
+
+  Source code of additional open source plugins shipped with IntelliJ IDEA is available in the Subversion
+  repository at:
+  http://svn.jetbrains.org/idea/Trunk/bundled/
+
+
+Using Plugins
+=============
+  IDEA now smartly integrates with the Community web-site which holds a repository of the third-party plugins to it.
+  This integration, supplied with a convenient UI, helps you incorporate any available plugins without switching from
+  IDEA settings dialog (Settings | Plugins).
+
+  You can browse the plugins Web site, rate and comment on plugins at:
+  http://plugins.intellij.net/
+
+
+Home Page:
+==========
+  http://www.jetbrains.com
+
+
+IntelliJ Technology Network
+===========================
+  http://www.intellij.net
+  Early Access to new products, internal builds and patches, Bug/Features database, Forums/newsgroups
+
+
+IntelliJ Community Site
+=======================
+  http://www.intellij.org
+  The community-driven Wiki site dedicated to IntelliJ products and technologies.
+
+
+Support
+=======
+  For technical support and assistance, you may find necessary information at the Support page
+  (http://www.jetbrains.com/support/index.html) or contact us at support@jetbrains.com.
+
+
+Bug Reporting:
+==============
+  Send emails to bugs@jetbrains.com
+
+
+Contacting us:
+==============
+  sales@jetbrains.com       - Sales inquiries, billing, order processing questions
+  support@jetbrains.com     - Technical support (all products)
+  sales.us@jetbrains.com    - Sales inquiries in the United States
+  support.us@jetbrains.com  - Technical support for US customers
+  suggestions@jetbrains.com - Feature suggestions
+  info@jetbrains.com        - Product inquiries
+
+
+=============
+You are encouraged to visit our IntelliJ IDEA web site at http://www.jetbrains.com/idea/
+or to contact us via e-mail at feedback@jetbrains.com if you have any comments about
+this release. In particular, we are very interested in any ease-of-use, user
+interface suggestions that you may have. We will be posting regular updates
+of our progress to our online forums and newsgroups.
+=============
diff --git a/updater/testData/bin/focuskiller.dll b/updater/testData/bin/focuskiller.dll
new file mode 100644 (file)
index 0000000..c1f8e04
Binary files /dev/null and b/updater/testData/bin/focuskiller.dll differ
diff --git a/updater/testData/bin/idea.bat b/updater/testData/bin/idea.bat
new file mode 100644 (file)
index 0000000..79a087f
--- /dev/null
@@ -0,0 +1,66 @@
+@echo off
+
+::----------------------------------------------------------------------
+:: IntelliJ IDEA Startup Script
+::----------------------------------------------------------------------
+
+set JDK_HOME=c:/tools/jdk
+
+:: ---------------------------------------------------------------------
+:: Before you run IntelliJ IDEA specify the location of the
+:: JDK 1.5 installation directory which will be used for running IDEA
+:: ---------------------------------------------------------------------
+IF "%IDEA_JDK%" == "" SET IDEA_JDK=%JDK_HOME%
+IF "%IDEA_JDK%" == "" goto error
+
+:: ---------------------------------------------------------------------
+:: Before you run IntelliJ IDEA specify the location of the
+:: directory where IntelliJ IDEA is installed
+:: In most cases you do not need to change the settings below.
+:: ---------------------------------------------------------------------
+SET IDEA_HOME=..
+
+SET JAVA_EXE=%IDEA_JDK%\jre\bin\java.exe
+IF NOT EXIST "%JAVA_EXE%" goto error
+
+IF "%IDEA_MAIN_CLASS_NAME%" == "" SET IDEA_MAIN_CLASS_NAME=com.intellij.idea.Main
+
+IF NOT "%IDEA_PROPERTIES%" == "" set IDEA_PROPERTIES_PROPERTY=-Didea.properties.file=%IDEA_PROPERTIES%
+
+:: ---------------------------------------------------------------------
+:: You may specify your own JVM arguments in idea.exe.vmoptions file. Put one option per line there.
+:: ---------------------------------------------------------------------
+SET ACC=
+FOR /F "delims=" %%i in (%IDEA_HOME%\bin\idea.exe.vmoptions) DO call %IDEA_HOME%\bin\append.bat "%%i"
+
+set REQUIRED_IDEA_JVM_ARGS=-Xbootclasspath/p:%IDEA_HOME%/lib/boot.jar %IDEA_PROPERTIES_PROPERTY% %REQUIRED_IDEA_JVM_ARGS%
+SET JVM_ARGS=%ACC% %REQUIRED_IDEA_JVM_ARGS%
+
+SET OLD_PATH=%PATH%
+SET PATH=%IDEA_HOME%\bin;%PATH%
+
+SET CLASS_PATH=%IDEA_HOME%\lib\bootstrap.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\util.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\jdom.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\log4j.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\extensions.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\trove4j.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_JDK%\lib\tools.jar
+
+:: ---------------------------------------------------------------------
+:: You may specify additional class paths in IDEA_CLASS_PATH variable.
+:: It is a good idea to specify paths to your plugins in this variable.
+:: ---------------------------------------------------------------------
+IF NOT "%IDEA_CLASS_PATH%" == "" SET CLASS_PATH=%CLASS_PATH%;%IDEA_CLASS_PATH%
+
+"%JAVA_EXE%" %JVM_ARGS% -cp "%CLASS_PATH%" %IDEA_MAIN_CLASS_NAME% %*
+
+SET PATH=%OLD_PATH%
+goto end
+:error
+echo ---------------------------------------------------------------------
+echo ERROR: cannot start IntelliJ IDEA.
+echo No JDK found to run IDEA. Please validate either IDEA_JDK or JDK_HOME points to valid JDK installation
+echo ---------------------------------------------------------------------
+pause
+:end
diff --git a/updater/testData/bin/idea.properties b/updater/testData/bin/idea.properties
new file mode 100644 (file)
index 0000000..37bc736
--- /dev/null
@@ -0,0 +1,105 @@
+# Set up IDEA_PROPERTIES environment variable to specify custom location of this properties file like
+# SET IDEA_PROPERTIES=c:\ideaconfig\idea.properties
+# before launching idea.
+# If not specified it is searched according following sequence (first successful is used).
+# 1. ${user.home}
+# 2. ${idea.home}/bin
+
+# Use ${idea.home} macro to specify location relative to IDEA installation home
+# Also use ${xxx} where xxx is any java property (including defined in previous lines of this file) to refer to its value
+# Note for Windows users: please make sure you're using forward slashes. I.e. c:/idea/system
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to IDEA config folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.config.path=${idea.home}/config
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to IDEA system folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.system.path=${idea.home}/system
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to user installed plugins folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.plugins.path=${idea.home}/config/plugins
+
+#---------------------------------------------------------------------
+# Maximum file size (kilobytes) IDEA should provide intellisense for.
+# The larger file is the slower its editor works and higher overall system memory requirements are
+# if intellisense is enabled. Remove this property or set to very large number if you need
+# intellisense for any files available regardless their size.
+# Please note this option doesn't operate with Java files. Regardless of the option value intellisense will anyway stay there.
+#---------------------------------------------------------------------
+idea.max.intellisense.filesize=2048
+
+#---------------------------------------------------------------------
+# There are two possible values of idea.popup.weight property: "heavy" and "medium".
+# If you have WM configured as "Focus follows mouse with Auto Raise" then you have to
+# set this property to "medium". It prevents problems with popup menus on some
+# configurations.
+# ---------------------------------------------------------------------
+idea.popup.weight=heavy
+
+#----------------------------------------------------------------------
+# Disabling this property may lead to visual glitches like blinking and fail to repaint
+# on certain display adapter cards.
+#----------------------------------------------------------------------
+sun.java2d.noddraw=true
+
+#----------------------------------------------------------------------
+# Removing this property may lead to editor performance degradation under Windows.
+#----------------------------------------------------------------------
+sun.java2d.d3d=false
+
+#-----------------------------------------------------------------------
+# IDEA copies library jars to prevent their locking. If copying is not desirable, specify "true"
+#-----------------------------------------------------------------------
+idea.jars.nocopy=false
+
+#----------------------------------------------------------------------
+# Configure if a special launcher should be used when running processes from within IDEA.
+# Using Launcher enables "soft exit" and "thread dump" features
+#----------------------------------------------------------------------
+idea.no.launcher=false
+
+#-----------------------------------------------------------------------
+# The VM option value to be used start the JVM in debug mode.
+# Some environments define it in a different way (-XXdebug in Oracle VM)
+#-----------------------------------------------------------------------
+idea.xdebug.key=-Xdebug
+
+#-----------------------------------------------------------------------
+# Switch into JMX 1.0 compatible mode
+# Uncomment this option to be able to run IDEA using J2SDK 1.5 while working
+# with application servers (like WebLogic) running 1.4
+#-----------------------------------------------------------------------
+#jmx.serial.form=1.0
+
+#-----------------------------------------------------------------------
+# Uncomment this option if you don't like to receive notifications about
+# fatal errors that happen to IDEA or plugins installed.
+#-----------------------------------------------------------------------
+idea.fatal.error.notification=disabled
+
+# Workaround for slow scrolling in JDK6
+swing.bufferPerWindow=false
+
+#-----------------------------------------------------------------------
+# Uncomment this property to prevent IDEA from throwing ProcessCanceledException when user activity
+# detected. This option is only useful for plugin developers, while debugging PSI related activities
+# performed in background error analysis thread.
+# DO NOT UNCOMMENT THIS UNLESS YOU'RE DEBUGGING IDEA ITSELF. Significant slowdowns and lockups will happen otherwise.
+#-----------------------------------------------------------------------
+#idea.ProcessCanceledException=disabled
+
+#----------------------------------------------------------------------
+# Removing this property may lead to editor performance degradation under X-Windows.
+#----------------------------------------------------------------------
+sun.java2d.pmoffscreen=false
+
+#---------------------------------------------------------------------
+# Maximum size (kilobytes) IDEA will load for showing past file contents -
+# in Show Diff or when calculating Digest Diff
+#---------------------------------------------------------------------
+#idea.max.vcs.loaded.size.kb=20480
\ No newline at end of file
diff --git a/updater/testData/lib/annotations.jar b/updater/testData/lib/annotations.jar
new file mode 100644 (file)
index 0000000..53f730f
Binary files /dev/null and b/updater/testData/lib/annotations.jar differ
diff --git a/updater/testData/lib/annotations_changed.jar b/updater/testData/lib/annotations_changed.jar
new file mode 100644 (file)
index 0000000..43af95c
Binary files /dev/null and b/updater/testData/lib/annotations_changed.jar differ
diff --git a/updater/testData/lib/boot.jar b/updater/testData/lib/boot.jar
new file mode 100644 (file)
index 0000000..98b408f
Binary files /dev/null and b/updater/testData/lib/boot.jar differ
diff --git a/updater/testData/lib/boot2.jar b/updater/testData/lib/boot2.jar
new file mode 100644 (file)
index 0000000..5c9c316
Binary files /dev/null and b/updater/testData/lib/boot2.jar differ
diff --git a/updater/testData/lib/boot2_changed_with_unchanged_content.jar b/updater/testData/lib/boot2_changed_with_unchanged_content.jar
new file mode 100644 (file)
index 0000000..c8eb3d9
Binary files /dev/null and b/updater/testData/lib/boot2_changed_with_unchanged_content.jar differ
diff --git a/updater/testData/lib/boot_with_directory_becomes_file.jar b/updater/testData/lib/boot_with_directory_becomes_file.jar
new file mode 100644 (file)
index 0000000..4c16379
Binary files /dev/null and b/updater/testData/lib/boot_with_directory_becomes_file.jar differ
diff --git a/updater/testData/lib/bootstrap.jar b/updater/testData/lib/bootstrap.jar
new file mode 100644 (file)
index 0000000..3a32734
Binary files /dev/null and b/updater/testData/lib/bootstrap.jar differ
diff --git a/updater/testData/lib/bootstrap_deleted.jar b/updater/testData/lib/bootstrap_deleted.jar
new file mode 100644 (file)
index 0000000..b0aed41
Binary files /dev/null and b/updater/testData/lib/bootstrap_deleted.jar differ
diff --git a/updater/testSrc/com/intellij/updater/DigesterTest.java b/updater/testSrc/com/intellij/updater/DigesterTest.java
new file mode 100644 (file)
index 0000000..a71041c
--- /dev/null
@@ -0,0 +1,21 @@
+package com.intellij.updater;
+
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class DigesterTest extends UpdaterTestCase {
+  @Test
+  public void testBasics() throws Exception {
+    Map<String, Long> checkSums = Digester.digestFiles(getDataDir(), Collections.<String>emptyList(), TEST_UI);
+    assertEquals(12, checkSums.size());
+
+    assertEquals(CHECKSUMS.README_TXT, (long)checkSums.get("Readme.txt"));
+    assertEquals(CHECKSUMS.FOCUSKILLER_DLL, (long)checkSums.get("bin/focuskiller.dll"));
+    assertEquals(CHECKSUMS.BOOTSTRAP_JAR, (long)checkSums.get("lib/bootstrap.jar"));
+    Runner.initLogger();
+  }
+}
\ No newline at end of file
diff --git a/updater/testSrc/com/intellij/updater/PatchFileCreatorTest.java b/updater/testSrc/com/intellij/updater/PatchFileCreatorTest.java
new file mode 100644 (file)
index 0000000..4e87db2
--- /dev/null
@@ -0,0 +1,333 @@
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import static org.junit.Assert.*;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class PatchFileCreatorTest extends PatchTestCase {
+  private File myFile;
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    myFile = getTempFile("patch.zip");
+  }
+
+  @Test
+  public void testCreatingAndApplying() throws Exception {
+    createPatch();
+
+    assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void failOnEmptySourceJar() throws Exception {
+    final File sourceJar = new File(myOlderDir, "lib/empty.jar");
+    if (sourceJar.exists()) sourceJar.delete();
+    assertTrue(sourceJar.createNewFile());
+
+    try {
+      final File targetJar = new File(myNewerDir, "lib/empty.jar");
+      FileUtil.copy(new File(myNewerDir, "lib/annotations.jar"), targetJar);
+
+      try {
+        createPatch();
+        fail("Should have failed to create a patch from empty .jar");
+      }
+      catch (IOException e) {
+        final String reason = e.getMessage();
+        assertEquals("Corrupted source file: " + sourceJar, reason);
+      }
+      finally {
+        targetJar.delete();
+      }
+    }
+    finally {
+      sourceJar.delete();
+    }
+  }
+
+  @Test
+  public void failOnEmptyTargetJar() throws Exception {
+    final File sourceJar = new File(myOlderDir, "lib/empty.jar");
+    FileUtil.copy(new File(myOlderDir, "lib/annotations.jar"), sourceJar);
+
+    try {
+      final File targetJar = new File(myNewerDir, "lib/empty.jar");
+      if (targetJar.exists()) targetJar.delete();
+      assertTrue(targetJar.createNewFile());
+
+      try {
+        createPatch();
+        fail("Should have failed to create a patch against empty .jar");
+      }
+      catch (IOException e) {
+        final String reason = e.getMessage();
+        assertEquals("Corrupted target file: " + targetJar, reason);
+      }
+      finally {
+        targetJar.delete();
+      }
+    }
+    finally {
+      sourceJar.delete();
+    }
+  }
+
+  @Test
+  public void testReverting() throws Exception {
+    createPatch();
+
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+    preparationResult.patch.getActions().add(new MyFailOnApplyPatchAction());
+    assertNothingHasChanged(preparationResult, new HashMap<String, ValidationResult.Option>());
+  }
+
+  @Test
+  public void testApplyingWithAbsentFileToDelete() throws Exception {
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    new File(myOlderDir, "bin/idea.bat").delete();
+
+    assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void testApplyingWithAbsentOptionalFile() throws Exception {
+    FileUtil.writeToFile(new File(myNewerDir, "bin/idea.bat"), "new content".getBytes());
+
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.singletonList("bin/idea.bat"), TEST_UI);
+
+    new File(myOlderDir, "bin/idea.bat").delete();
+
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+    assertTrue(preparationResult.validationResults.isEmpty());
+    assertAppliedAndRevertedCorrectly(preparationResult);
+  }
+
+  @Test
+  public void testRevertingWithAbsentFileToDelete() throws Exception {
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    new File(myOlderDir, "bin/idea.bat").delete();
+
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+    preparationResult.patch.getActions().add(new MyFailOnApplyPatchAction());
+    assertNothingHasChanged(preparationResult, new HashMap<String, ValidationResult.Option>());
+  }
+
+  @Test
+  public void testApplyingWithoutCriticalFiles() throws Exception {
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+
+    assertTrue(PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), TEST_UI));
+  }
+
+  @Test
+  public void testApplyingWithCriticalFiles() throws Exception {
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Arrays.asList("lib/annotations.jar"),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+
+    assertTrue(PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), TEST_UI));
+    assertAppliedCorrectly();
+  }
+
+  @Test
+  public void testApplyingWithCaseChangedNames() throws Exception {
+    FileUtil.rename(new File(myOlderDir, "Readme.txt"),
+                    new File(myOlderDir, "README.txt"));
+
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void testCreatingAndApplyingWhenDirectoryBecomesFile() throws Exception {
+    File file = new File(myOlderDir, "Readme.txt");
+    file.delete();
+    file.mkdirs();
+
+    new File(file, "subFile.txt").createNewFile();
+    new File(file, "subDir").mkdir();
+    new File(file, "subDir/subFile.txt").createNewFile();
+
+    FileUtil.copy(new File(myOlderDir, "lib/boot.jar"),
+                  new File(myOlderDir, "lib/boot_with_directory_becomes_file.jar"));
+
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void testCreatingAndApplyingWhenFileBecomesDirectory() throws Exception {
+    File file = new File(myOlderDir, "bin");
+    assertTrue(FileUtil.delete(file));
+    file.createNewFile();
+
+    FileUtil.copy(new File(myOlderDir, "lib/boot_with_directory_becomes_file.jar"),
+                  new File(myOlderDir, "lib/boot.jar"));
+
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                            Collections.<String>emptyList(), TEST_UI);
+
+    assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void testConsideringOptions() throws Exception {
+    createPatch();
+
+    PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+    Map<String, ValidationResult.Option> options = new HashMap<String, ValidationResult.Option>();
+    for (PatchAction each : preparationResult.patch.getActions()) {
+      options.put(each.getPath(), ValidationResult.Option.IGNORE);
+    }
+
+    assertNothingHasChanged(preparationResult, options);
+  }
+
+  private void createPatch() throws IOException, OperationCancelledException {
+    PatchFileCreator.create(myOlderDir, myNewerDir, myFile,
+                            Collections.<String>emptyList(), Collections.<String>emptyList(), Collections.<String>emptyList(), TEST_UI);
+    assertTrue(myFile.exists());
+  }
+
+  private void assertNothingHasChanged(PatchFileCreator.PreparationResult preparationResult, Map<String, ValidationResult.Option> options)
+    throws Exception {
+    Map<String, Long> before = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+    PatchFileCreator.apply(preparationResult, options, TEST_UI);
+    Map<String, Long> after = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+
+    DiffCalculator.Result diff = DiffCalculator.calculate(before, after);
+    assertTrue(diff.filesToCreate.isEmpty());
+    assertTrue(diff.filesToDelete.isEmpty());
+    assertTrue(diff.filesToUpdate.isEmpty());
+  }
+
+  private void assertAppliedAndRevertedCorrectly(PatchFileCreator.PreparationResult preparationResult)
+    throws IOException, OperationCancelledException {
+
+    Map<String, Long> original = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+
+    File backup = getTempFile("backup");
+
+    for (ValidationResult each : preparationResult.validationResults) {
+      assertTrue(each.toString(), each.kind != ValidationResult.Kind.ERROR);
+    }
+
+    List<PatchAction> appliedActions =
+      PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), backup, TEST_UI).appliedActions;
+    assertAppliedCorrectly();
+
+    assertFalse(original.equals(Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI)));
+
+    PatchFileCreator.revert(preparationResult, appliedActions, backup, TEST_UI);
+
+    assertEquals(original, Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI));
+  }
+
+  protected void assertAppliedCorrectly() throws IOException {
+    File newFile = new File(myOlderDir, "newDir/newFile.txt");
+    assertTrue(newFile.exists());
+    assertEquals("hello", FileUtil.loadFile(newFile));
+
+    File changedFile = new File(myOlderDir, "Readme.txt");
+    assertTrue(changedFile.exists());
+    assertEquals("hello", FileUtil.loadFile(changedFile));
+
+    assertFalse(new File(myOlderDir, "bin/idea.bat").exists());
+
+    // do not remove unchanged
+    checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/Nls.class", 502);
+    // add new
+    checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/NewClass.class", 453);
+    // update changed
+    checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/Nullable.class", 546);
+    // remove obsolete
+    checkNoZipEntry("lib/annotations.jar", "org/jetbrains/annotations/TestOnly.class");
+
+    // test for archives with only deleted files
+    checkNoZipEntry("lib/bootstrap.jar", "com/intellij/ide/ClassloaderUtil.class");
+
+    // packing directories too
+    checkZipEntry("lib/annotations.jar", "org/", 0);
+    checkZipEntry("lib/annotations.jar", "org/jetbrains/", 0);
+    checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/", 0);
+    checkZipEntry("lib/bootstrap.jar", "com/", 0);
+    checkZipEntry("lib/bootstrap.jar", "com/intellij/", 0);
+    checkZipEntry("lib/bootstrap.jar", "com/intellij/ide/", 0);
+  }
+
+  private void checkZipEntry(String jar, String entryName, int expectedSize) throws IOException {
+    ZipFile zipFile = new ZipFile(new File(myOlderDir, jar));
+    try {
+      ZipEntry entry = zipFile.getEntry(entryName);
+      assertNotNull(entry);
+      assertEquals(expectedSize, entry.getSize());
+    }
+    finally {
+      zipFile.close();
+    }
+  }
+
+  private void checkNoZipEntry(String jar, String entryName) throws IOException {
+    ZipFile zipFile = new ZipFile(new File(myOlderDir, jar));
+    try {
+      assertNull(zipFile.getEntry(entryName));
+    }
+    finally {
+      zipFile.close();
+    }
+  }
+
+  private static class MyFailOnApplyPatchAction extends PatchAction {
+    public MyFailOnApplyPatchAction() {
+      super("_dummy_file_", -1);
+    }
+
+    @Override
+    protected void doBuildPatchFile(File olderFile, File newerFile, ZipOutputStream patchOutput) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected ValidationResult doValidate(File toFile) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void doApply(ZipFile patchFile, File toFile) throws IOException {
+      throw new IOException("dummy exception");
+    }
+
+    @Override
+    protected void doBackup(File toFile, File backupFile) throws IOException {
+    }
+
+    @Override
+    protected void doRevert(File toFile, File backupFile) throws IOException {
+    }
+  }
+}
diff --git a/updater/testSrc/com/intellij/updater/PatchTest.java b/updater/testSrc/com/intellij/updater/PatchTest.java
new file mode 100644 (file)
index 0000000..14ff6c0
--- /dev/null
@@ -0,0 +1,192 @@
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.channels.FileLock;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class PatchTest extends PatchTestCase {
+  private Patch myPatch;
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    myPatch = new Patch(myOlderDir, myNewerDir, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                        Collections.<String>emptyList(), TEST_UI);
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    List<PatchAction> expectedActions = Arrays.asList(
+      new CreateAction("newDir/newFile.txt"),
+      new UpdateAction("Readme.txt", CHECKSUMS.README_TXT),
+      new UpdateZipAction("lib/annotations.jar",
+                          Arrays.asList("org/jetbrains/annotations/NewClass.class"),
+                          Arrays.asList("org/jetbrains/annotations/Nullable.class"),
+                          Arrays.asList("org/jetbrains/annotations/TestOnly.class"),
+                          CHECKSUMS.ANNOTATIONS_JAR),
+      new UpdateZipAction("lib/bootstrap.jar",
+                          Collections.<String>emptyList(),
+                          Collections.<String>emptyList(),
+                          Arrays.asList("com/intellij/ide/ClassloaderUtil.class"),
+                          CHECKSUMS.BOOTSTRAP_JAR),
+      new DeleteAction("bin/idea.bat", CHECKSUMS.IDEA_BAT));
+    List<PatchAction> actualActions = new ArrayList<PatchAction>(myPatch.getActions());
+    Collections.sort(expectedActions, COMPARATOR);
+    Collections.sort(actualActions, COMPARATOR);
+    assertEquals(expectedActions, actualActions);
+  }
+
+  @Test
+  public void testCreatingWithIgnoredFiles() throws Exception {
+    myPatch = new Patch(myOlderDir,
+                        myNewerDir,
+                        Arrays.asList("Readme.txt", "bin/idea.bat"),
+                        Collections.<String>emptyList(),
+                        Collections.<String>emptyList(),
+                        TEST_UI);
+
+    List<PatchAction> expectedActions = Arrays.asList(
+      new CreateAction("newDir/newFile.txt"),
+      new UpdateZipAction("lib/annotations.jar",
+                          Arrays.asList("org/jetbrains/annotations/NewClass.class"),
+                          Arrays.asList("org/jetbrains/annotations/Nullable.class"),
+                          Arrays.asList("org/jetbrains/annotations/TestOnly.class"),
+                          CHECKSUMS.ANNOTATIONS_JAR),
+      new UpdateZipAction("lib/bootstrap.jar",
+                          Collections.<String>emptyList(),
+                          Collections.<String>emptyList(),
+                          Arrays.asList("com/intellij/ide/ClassloaderUtil.class"),
+                          CHECKSUMS.BOOTSTRAP_JAR));
+    List<PatchAction> actualActions = new ArrayList<PatchAction>(myPatch.getActions());
+    Collections.sort(expectedActions, COMPARATOR);
+    Collections.sort(actualActions, COMPARATOR);
+    assertEquals(expectedActions, actualActions);
+  }
+
+  @Test
+  public void testValidation() throws Exception {
+    FileUtil.writeToFile(new File(myOlderDir, "bin/idea.bat"), "changed".getBytes());
+    new File(myOlderDir, "extraDir").mkdirs();
+    new File(myOlderDir, "extraDir/extraFile.txt").createNewFile();
+    new File(myOlderDir, "newDir").mkdirs();
+    new File(myOlderDir, "newDir/newFile.txt").createNewFile();
+    FileUtil.writeToFile(new File(myOlderDir, "Readme.txt"), "changed".getBytes());
+    FileUtil.writeToFile(new File(myOlderDir, "lib/annotations.jar"), "changed".getBytes());
+    FileUtil.delete(new File(myOlderDir, "lib/bootstrap.jar"));
+
+    assertEquals(
+      new HashSet<ValidationResult>(Arrays.asList(
+        new ValidationResult(ValidationResult.Kind.CONFLICT,
+                             "newDir/newFile.txt",
+                             ValidationResult.Action.CREATE,
+                             ValidationResult.ALREADY_EXISTS_MESSAGE,
+                             ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP),
+        new ValidationResult(ValidationResult.Kind.ERROR,
+                             "Readme.txt",
+                             ValidationResult.Action.UPDATE,
+                             ValidationResult.MODIFIED_MESSAGE,
+                             ValidationResult.Option.IGNORE),
+        new ValidationResult(ValidationResult.Kind.ERROR,
+                             "lib/annotations.jar",
+                             ValidationResult.Action.UPDATE,
+                             ValidationResult.MODIFIED_MESSAGE,
+                             ValidationResult.Option.IGNORE),
+        new ValidationResult(ValidationResult.Kind.ERROR,
+                             "lib/bootstrap.jar",
+                             ValidationResult.Action.UPDATE,
+                             ValidationResult.ABSENT_MESSAGE,
+                             ValidationResult.Option.IGNORE),
+        new ValidationResult(ValidationResult.Kind.CONFLICT,
+                             "bin/idea.bat",
+                             ValidationResult.Action.DELETE,
+                             ValidationResult.MODIFIED_MESSAGE,
+                             ValidationResult.Option.DELETE, ValidationResult.Option.KEEP))),
+      new HashSet<ValidationResult>(myPatch.validate(myOlderDir, TEST_UI)));
+  }
+
+  @Test
+  public void testValidationWithOptionalFiles() throws Exception {
+    FileUtil.writeToFile(new File(myOlderDir, "lib/annotations.jar"), "changed".getBytes());
+    assertEquals(new HashSet<ValidationResult>(Arrays.asList(
+      new ValidationResult(ValidationResult.Kind.ERROR,
+                           "lib/annotations.jar",
+                           ValidationResult.Action.UPDATE,
+                           ValidationResult.MODIFIED_MESSAGE,
+                           ValidationResult.Option.IGNORE))),
+                 new HashSet<ValidationResult>(myPatch.validate(myOlderDir, TEST_UI)));
+
+    myPatch = new Patch(myOlderDir, myNewerDir, Collections.<String>emptyList(), Collections.<String>emptyList(),
+                        Arrays.asList("lib/annotations.jar"), TEST_UI);
+    FileUtil.delete(new File(myOlderDir, "lib/annotations.jar"));
+    assertEquals(Collections.<ValidationResult>emptyList(),
+                 myPatch.validate(myOlderDir, TEST_UI));
+  }
+
+  @Test
+  public void testValidatingNonAccessibleFiles() throws Exception {
+    File f = new File(myOlderDir, "Readme.txt");
+    FileOutputStream s = new FileOutputStream(f, true);
+    try {
+      FileLock lock = s.getChannel().lock();
+      try {
+        List<ValidationResult> result = myPatch.validate(myOlderDir, TEST_UI);
+        assertEquals(
+          new HashSet<ValidationResult>(Arrays.asList(
+            new ValidationResult(ValidationResult.Kind.ERROR,
+                                 "Readme.txt",
+                                 ValidationResult.Action.UPDATE,
+                                 ValidationResult.ACCESS_DENIED_MESSAGE,
+                                 ValidationResult.Option.IGNORE))),
+          new HashSet<ValidationResult>(result));
+      }
+      finally {
+        lock.release();
+      }
+    }
+    finally {
+      s.close();
+    }
+  }
+
+  @Test
+  public void testSaveLoad() throws Exception {
+    File f = getTempFile("file");
+    try {
+      FileOutputStream out = new FileOutputStream(f);
+      try {
+        myPatch.write(out);
+      }
+      finally {
+        out.close();
+      }
+
+      FileInputStream in = new FileInputStream(f);
+      try {
+        assertEquals(myPatch.getActions(), new Patch(in).getActions());
+      }
+      finally {
+        in.close();
+      }
+    }
+    finally {
+      f.delete();
+    }
+  }
+
+  private static final Comparator<PatchAction> COMPARATOR = new Comparator<PatchAction>() {
+    @Override
+    public int compare(PatchAction o1, PatchAction o2) {
+      return o1.toString().compareTo(o2.toString());
+    }
+  };
+}
diff --git a/updater/testSrc/com/intellij/updater/PatchTestCase.java b/updater/testSrc/com/intellij/updater/PatchTestCase.java
new file mode 100644 (file)
index 0000000..417c32e
--- /dev/null
@@ -0,0 +1,41 @@
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+
+import java.io.File;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public abstract class PatchTestCase extends UpdaterTestCase {
+  protected File myNewerDir;
+  protected File myOlderDir;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    myOlderDir = getDataDir();
+    myNewerDir = getTempFile("newDir");
+    FileUtil.copyDir(myOlderDir, myNewerDir);
+
+    FileUtil.delete(new File(myNewerDir, "bin/idea.bat"));
+    FileUtil.writeToFile(new File(myNewerDir, "Readme.txt"), "hello".getBytes());
+    File newFile = new File(myNewerDir, "newDir/newFile.txt");
+    newFile.getParentFile().mkdirs();
+    newFile.createNewFile();
+    FileUtil.writeToFile(newFile, "hello".getBytes());
+
+    FileUtil.delete(new File(myOlderDir, "lib/annotations_changed.jar"));
+    FileUtil.delete(new File(myNewerDir, "lib/annotations.jar"));
+    FileUtil.rename(new File(myNewerDir, "lib/annotations_changed.jar"),
+                    new File(myNewerDir, "lib/annotations.jar"));
+
+    FileUtil.delete(new File(myOlderDir, "lib/bootstrap_deleted.jar"));
+    FileUtil.delete(new File(myNewerDir, "lib/bootstrap.jar"));
+    FileUtil.rename(new File(myNewerDir, "lib/bootstrap_deleted.jar"),
+                    new File(myNewerDir, "lib/bootstrap.jar"));
+
+    FileUtil.delete(new File(myOlderDir, "lib/boot2_changed_with_unchanged_content.jar"));
+    FileUtil.delete(new File(myNewerDir, "lib/boot2.jar"));
+    FileUtil.rename(new File(myNewerDir, "lib/boot2_changed_with_unchanged_content.jar"),
+                    new File(myNewerDir, "lib/boot2.jar"));
+  }
+}
\ No newline at end of file
diff --git a/updater/testSrc/com/intellij/updater/RunnerTest.java b/updater/testSrc/com/intellij/updater/RunnerTest.java
new file mode 100644 (file)
index 0000000..22464a0
--- /dev/null
@@ -0,0 +1,25 @@
+package com.intellij.updater;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+
+public class RunnerTest extends UpdaterTestCase {
+  @Test
+  public void testExtractingFiles() throws Exception {
+    String[] args = {"bar", "ignored=xxx;yyy;zzz/zzz", "critical=", "ignored=aaa", "baz", "critical=ccc"};
+    Runner.initLogger();
+
+    assertEquals(Arrays.asList("xxx", "yyy", "zzz/zzz", "aaa"),
+                 Runner.extractFiles(args, "ignored"));
+
+    assertEquals(Arrays.asList("ccc"),
+                 Runner.extractFiles(args, "critical"));
+
+    assertEquals(Collections.<String>emptyList(),
+                 Runner.extractFiles(args, "unknown"));
+  }
+}
diff --git a/updater/testSrc/com/intellij/updater/UpdaterTestCase.java b/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
new file mode 100644 (file)
index 0000000..9bde5c8
--- /dev/null
@@ -0,0 +1,72 @@
+package com.intellij.updater;
+
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
+import com.intellij.testFramework.fixtures.TempDirTestFixture;
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.File;
+
+public abstract class UpdaterTestCase {
+  protected static final UpdaterUI TEST_UI = new ConsoleUpdaterUI(){
+    @Override
+    public void startProcess(String title) {
+    }
+
+    @Override
+    public void setStatus(String status) {
+    }
+  };
+
+  protected CheckSums CHECKSUMS;
+  private TempDirTestFixture myTempDirFixture;
+
+  @Before
+  public void setUp() throws Exception {
+    myTempDirFixture = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
+    myTempDirFixture.setUp();
+
+    FileUtil.copyDir(PathManagerEx.findFileUnderCommunityHome("updater/testData"), getDataDir());
+
+    boolean windowsLineEnds = new File(getDataDir(), "Readme.txt").length() == 7132;
+    CHECKSUMS = new CheckSums(windowsLineEnds);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    myTempDirFixture.tearDown();
+    Utils.cleanup();
+  }
+
+  public File getDataDir() {
+    return getTempFile("data");
+  }
+
+  public File getTempFile(String fileName) {
+    return new File(myTempDirFixture.getTempDirPath(), fileName);
+  }
+
+  protected static class CheckSums {
+    public final long README_TXT;
+    public final long IDEA_BAT;
+    public final long ANNOTATIONS_JAR;
+    public final long BOOTSTRAP_JAR;
+    public final long FOCUSKILLER_DLL;
+
+    public CheckSums(boolean windowsLineEnds) {
+      if (windowsLineEnds) {
+        README_TXT = 1272723667L;
+        IDEA_BAT = 3088608749L;
+      }
+      else {
+        README_TXT = 7256327L;
+        IDEA_BAT = 1493936069L;
+      }
+      ANNOTATIONS_JAR = 2119442657L;
+      BOOTSTRAP_JAR = 2082851308L;
+      FOCUSKILLER_DLL = 1991212227L;
+    }
+  }
+}
\ No newline at end of file
index a002577c561e5d1992176e2c50d48cbf75137c26..e55b58d17cd009d5061d6c0ccca71dff5a52edd8 100644 (file)
@@ -4,10 +4,13 @@
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="Log4J" level="project" />
+    <orderEntry type="module" module-name="testFramework" scope="TEST" />
+    <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
   </component>
 </module>