- Issue 106: Add splash screen just under progress bar, and load all cards at startup.

This commit is contained in:
Braids
2011-08-19 02:22:03 +00:00
parent c260a283cd
commit fdb1199223
8 changed files with 400 additions and 109 deletions

1
.gitattributes vendored
View File

@@ -9735,6 +9735,7 @@ src/main/java/forge/view/package-info.java svneol=native#text/plain
src/main/java/forge/view/swing/ApplicationView.java svneol=native#text/plain src/main/java/forge/view/swing/ApplicationView.java svneol=native#text/plain
src/main/java/forge/view/swing/Main.java svneol=native#text/plain src/main/java/forge/view/swing/Main.java svneol=native#text/plain
src/main/java/forge/view/swing/OldGuiNewGame.java svneol=native#text/plain src/main/java/forge/view/swing/OldGuiNewGame.java svneol=native#text/plain
src/main/java/forge/view/swing/SplashFrame.java -text
src/main/java/forge/view/swing/package-info.java svneol=native#text/plain src/main/java/forge/view/swing/package-info.java svneol=native#text/plain
src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain
src/main/java/net/slightlymagic/braids/util/ClumsyRunnable.java svneol=native#text/plain src/main/java/net/slightlymagic/braids/util/ClumsyRunnable.java svneol=native#text/plain

View File

@@ -1,16 +1,12 @@
package forge; package forge;
import com.google.code.jyield.Generator; import java.io.BufferedReader;
import com.google.code.jyield.YieldUtils; import java.io.File;
import forge.card.trigger.TriggerHandler; import java.io.FileInputStream;
import forge.error.ErrorViewer; import java.io.FileNotFoundException;
import forge.gui.MultiPhaseProgressMonitorWithETA; import java.io.IOException;
import forge.properties.NewConstants; import java.io.InputStream;
import net.slightlymagic.braids.util.UtilFunctions; import java.io.InputStreamReader;
import net.slightlymagic.braids.util.generator.FindNonDirectoriesSkipDotDirectoriesGenerator;
import net.slightlymagic.braids.util.generator.GeneratorFunctions;
import java.io.*;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Locale; import java.util.Locale;
@@ -20,6 +16,20 @@ import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import net.slightlymagic.braids.util.UtilFunctions;
import net.slightlymagic.braids.util.generator.FindNonDirectoriesSkipDotDirectoriesGenerator;
import net.slightlymagic.braids.util.generator.GeneratorFunctions;
import net.slightlymagic.braids.util.progress_monitor.BraidsProgressMonitor;
import net.slightlymagic.braids.util.progress_monitor.StderrProgressMonitor;
import com.google.code.jyield.Generator;
import com.google.code.jyield.YieldUtils;
import forge.card.trigger.TriggerHandler;
import forge.error.ErrorViewer;
import forge.properties.NewConstants;
import forge.view.FView;
/** /**
* <p>CardReader class.</p> * <p>CardReader class.</p>
@@ -165,12 +175,19 @@ public class CardReader implements Runnable, NewConstants {
protected final Card loadCardsUntilYouFind(final String cardName) { protected final Card loadCardsUntilYouFind(final String cardName) {
Card result = null; Card result = null;
MultiPhaseProgressMonitorWithETA monitor; BraidsProgressMonitor monitor = null;
final FView view = Singletons.getView();
if (view != null) {
monitor = view.getCardLoadingProgressMonitor();
}
if (monitor == null) {
monitor = new StderrProgressMonitor(1, 0L);
}
if (zip != null) { if (zip != null) {
monitor = new MultiPhaseProgressMonitorWithETA("Forge - Loading card database from zip file", 1, monitor.setTotalUnitsThisPhase(estimatedFilesRemaining);
estimatedFilesRemaining, 1.0f);
ZipEntry entry; ZipEntry entry;
// zipEnum was initialized in the constructor. // zipEnum was initialized in the constructor.
@@ -197,8 +214,7 @@ public class CardReader implements Runnable, NewConstants {
findNonDirsIterable = YieldUtils.toIterable(findNonDirsGen); findNonDirsIterable = YieldUtils.toIterable(findNonDirsGen);
} }
monitor = new MultiPhaseProgressMonitorWithETA("Forge - Loading card database from files", 1, monitor.setTotalUnitsThisPhase(estimatedFilesRemaining);
estimatedFilesRemaining, 1.0f);
for (File cardTxtFile : findNonDirsIterable) { for (File cardTxtFile : findNonDirsIterable) {
if (!cardTxtFile.getName().endsWith(".txt")) { if (!cardTxtFile.getName().endsWith(".txt")) {

View File

@@ -1,9 +1,14 @@
package forge.gui; package forge.gui;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.Gui_ProgressBarWindow; import forge.Gui_ProgressBarWindow;
import net.slightlymagic.braids.util.UtilFunctions;
import net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor; import net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor;
/** /**
@@ -32,7 +37,11 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
} }
/** /**
* Create a GUI progress monitor and open its first dialog. * Create a GUI progress monitor and open its first dialog.
* *
* Like all swing components, this constructor must be invoked from the
* swing Event Dispatching Thread. The rest of the methods of this class
* are exempt from this requirement.
*
* @param title the title to give the dialog box(es) * @param title the title to give the dialog box(es)
* *
* @param numPhases the total number of phases to expect * @param numPhases the total number of phases to expect
@@ -51,108 +60,150 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
long totalUnitsFirstPhase, float minUIUpdateIntervalSec, long totalUnitsFirstPhase, float minUIUpdateIntervalSec,
float[] phaseWeights) float[] phaseWeights)
{ {
super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec,
phaseWeights); phaseWeights);
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from within an event dispatch thread");
}
this.title = title; this.title = title;
if (totalUnitsFirstPhase > 0 && dialog == null) {
throw new IllegalStateException("dialog is null");
}
} }
/** /**
* For developer testing. * For developer testing.
*
* @param args ignored
*/ */
public static void main(String[] args) { public static void main(final String[] args) {
System.out.println("Initializing..."); System.out.println("Initializing...");
MultiPhaseProgressMonitorWithETA monitor = SwingUtilities.invokeLater(new Runnable() {
new MultiPhaseProgressMonitorWithETA("Testing 2 phases", 2, 5000, public void run() {
1.0f, null);
System.out.println("Running...");
for (int i = 0; i <= 5000; i++) { final int totalUnitsFirstPhase = 5000;
monitor.incrementUnitsCompletedThisPhase(1); final MultiPhaseProgressMonitorWithETA monitor =
new MultiPhaseProgressMonitorWithETA("Testing 2 phases", 2, totalUnitsFirstPhase, 1.0f,
System.out.print("\ri = " + i); new float[] {2, 1});
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {
;
}
}
System.out.println();
monitor.markCurrentPhaseAsComplete(2000);
for (int i = 0; i <= 2000; i++) { SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() {
monitor.incrementUnitsCompletedThisPhase(1); @Override
public Object doInBackground() {
System.out.print("\ri = " + i);
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {
;
}
}
monitor.markCurrentPhaseAsComplete(0);
System.out.println(); System.out.println("Running...");
System.out.println("Done!"); for (int i = 0; i <= totalUnitsFirstPhase; i++) {
monitor.incrementUnitsCompletedThisPhase(1);
System.out.print("\ri = " + i);
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {
// blank
}
}
System.out.println();
final int totalUnitsSecondPhase = 2000;
monitor.markCurrentPhaseAsComplete(totalUnitsSecondPhase);
for (int i = 0; i <= totalUnitsSecondPhase; i++) {
monitor.incrementUnitsCompletedThisPhase(1);
System.out.print("\ri = " + i);
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {
// blank
}
}
monitor.markCurrentPhaseAsComplete(0);
System.out.println();
System.out.println("Done!");
return null;
}
};
worker.execute();
}
});
} }
@Override @Override
/** /**
* @param numUnits cannot be higher than Integer.MAX_VALUE * @param numUnits cannot be higher than Integer.MAX_VALUE
* *
* @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#setTotalUnitsThisPhase(long) * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#setTotalUnitsThisPhase(long)
*/ */
public void setTotalUnitsThisPhase(long numUnits) { public void setTotalUnitsThisPhase(final long numUnits) {
super.setTotalUnitsThisPhase(numUnits); super.setTotalUnitsThisPhase(numUnits);
if (numUnits > Integer.MAX_VALUE) { if (numUnits > Integer.MAX_VALUE) {
throw new IllegalArgumentException("numUnits must be <= " + Integer.MAX_VALUE); throw new IllegalArgumentException("numUnits must be <= " + Integer.MAX_VALUE);
} }
if (numUnits > 0) { if (numUnits > 0) {
// (Re)create the progress bar. // dialog must exist before we exit this method.
if (dialog != null) { UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() {
dialog.dispose(); public void run() {
dialog = null; // (Re)create the progress bar.
} if (dialog != null) {
dialog.dispose();
dialog = new Gui_ProgressBarWindow(); dialog = null;
dialog.setTitle(title); }
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true); dialog = new Gui_ProgressBarWindow();
dialog.setResizable(true); }
dialog.getProgressBar().setIndeterminate(false); });
dialog.setProgressRange(0, (int) numUnits); }
dialog.reset();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
dialog.setTitle(title);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
dialog.setResizable(true);
dialog.getProgressBar().setIndeterminate(false);
dialog.setProgressRange(0, (int) numUnits);
dialog.reset();
JProgressBar bar = dialog.getProgressBar();
bar.setString("");
bar.setStringPainted(true);
bar.setValue(0);
}
});
JProgressBar bar = dialog.getProgressBar();
bar.setString("");
bar.setStringPainted(true);
bar.setValue(0);
}
} }
@Override @Override
/** /**
* @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long) * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long)
*/ */
public void incrementUnitsCompletedThisPhase(long numUnits) { public void incrementUnitsCompletedThisPhase(final long numUnits) {
super.incrementUnitsCompletedThisPhase(numUnits); super.incrementUnitsCompletedThisPhase(numUnits);
for (int i = 0 ; i < numUnits ; i++) { SwingUtilities.invokeLater(new Runnable() {
dialog.increment(); public void run() {
} for (int i = 0 ; i < numUnits ; i++) {
dialog.increment();
}
}
});
if (shouldUpdateUI()) { if (shouldUpdateUI()) {
@@ -187,23 +238,38 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor {
* *
* @param message the message to display * @param message the message to display
*/ */
public void displayUpdate(String message) { public void displayUpdate(final String message) {
// i've been having trouble getting the dialog to display its title. final Runnable proc = new Runnable() {
dialog.setTitle(title); public void run() {
// i've been having trouble getting the dialog to display its title.
dialog.setTitle(title);
JProgressBar bar = dialog.getProgressBar(); JProgressBar bar = dialog.getProgressBar();
bar.setString(message); bar.setString(message);
justUpdatedUI(); justUpdatedUI();
}
};
if (SwingUtilities.isEventDispatchThread()) {
proc.run();
}
else {
SwingUtilities.invokeLater(proc);
}
} }
@Override @Override
public void dispose() { public final void dispose() {
getDialog().dispose(); SwingUtilities.invokeLater(new Runnable() {
public void run() {
getDialog().dispose();
}
});
} }
/** /**
* @return the JDialog for the current phase; use this judiciously to * @return the JDialog for the current phase; use this judiciously to

View File

@@ -1,5 +1,6 @@
package forge.view; package forge.view;
import net.slightlymagic.braids.util.progress_monitor.BraidsProgressMonitor;
import forge.model.FModel; import forge.model.FModel;
/** /**
@@ -15,4 +16,11 @@ public interface FView {
*/ */
void setModel(FModel model); void setModel(FModel model);
/**
* Get the progress monitor for loading all cards at once.
*
* @return a progress monitor having only one phase; may be null
*/
BraidsProgressMonitor getCardLoadingProgressMonitor();
} }

View File

@@ -1,8 +1,13 @@
package forge.view.swing; package forge.view.swing;
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import net.slightlymagic.braids.util.UtilFunctions;
import net.slightlymagic.braids.util.progress_monitor.BraidsProgressMonitor;
import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log;
import forge.AllZone; import forge.AllZone;
@@ -22,11 +27,46 @@ import forge.view.swing.OldGuiNewGame.CardStackOffsetAction;
* The main view for Forge: a java swing application. * The main view for Forge: a java swing application.
*/ */
public class ApplicationView implements FView { public class ApplicationView implements FView {
private SplashFrame splashFrame;
/** /**
* Constructor. * The splashFrame field is guaranteed to exist when this constructor
* exits.
*/ */
public ApplicationView() { // NOPMD by Braids on 8/7/11 1:14 PM: Damnation if it's here; Damnation if it's not. public ApplicationView() {
// TODO: insert splash window here
// We must use invokeAndWait here to fulfill the constructor's
// contract.
UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() {
public void run() {
splashFrame = new SplashFrame();
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
splashFrame.setVisible(true);
}
});
}
/* (non-Javadoc)
* @see forge.view.FView#getCardLoadingProgressMonitor()
*/
@Override
public final BraidsProgressMonitor getCardLoadingProgressMonitor() {
BraidsProgressMonitor result;
if (splashFrame == null) {
result = null;
}
else {
result = splashFrame.getMonitor();
}
return result;
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -73,11 +113,23 @@ public class ApplicationView implements FView {
} }
}); });
AllZone.getCardFactory(); // forces preloading of all cards
try { try {
Constant.Runtime.GameType[0] = Constant.GameType.Constructed; Constant.Runtime.GameType[0] = Constant.GameType.Constructed;
SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/7/11 1:07 PM: this isn't a web app SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/7/11 1:07 PM: this isn't a web app
public void run() { public void run() {
AllZone.setComputer(new ComputerAI_Input(new ComputerAI_General())); AllZone.setComputer(new ComputerAI_Input(new ComputerAI_General()));
getCardLoadingProgressMonitor().dispose();
// Enable only one of the following two lines. The second
// is useful for debugging.
splashFrame.dispose();
//splashFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
splashFrame = null;
new OldGuiNewGame(); new OldGuiNewGame();
} }
}); });
@@ -85,6 +137,5 @@ public class ApplicationView implements FView {
ErrorViewer.showError(ex); ErrorViewer.showError(ex);
} }
} }
} }

View File

@@ -0,0 +1,118 @@
package forge.view.swing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import forge.gui.MultiPhaseProgressMonitorWithETA;
/**
* Shows the splash frame as the application starts.
*/
@SuppressWarnings("serial")
public class SplashFrame extends JFrame {
private static final Color WHITE_COLOR = new Color(255, 255, 255);
private static final int DISCLAIMER_EAST_WEST_PADDING_PX = 40; // NOPMD by Braids on 8/17/11 9:06 PM
private static final int DISCLAIMER_FONT_SIZE = 9; // NOPMD by Braids on 8/17/11 9:06 PM
private static final int DISCLAIMER_NORTH_PADDING_PX = 300; // NOPMD by Braids on 8/17/11 9:06 PM
private static final int DISCLAIMER_HEIGHT_PX = 20; // NOPMD by Braids on 8/17/11 9:06 PM
private MultiPhaseProgressMonitorWithETA monitor;
/**
* <p>Create the frame; this <strong>must</strong> be called from an event
* dispatch thread.</p>
*
* <!-- CheckStyle won't let me use at-throws. -->
* throws {@link IllegalStateException} if not called from an event
* dispatch thread.
*/
public SplashFrame() {
super();
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from an event dispatch thread");
}
setUndecorated(true);
final ImageIcon bgIcon = new ImageIcon("res/images/ui/forgeSplash by moomarc.jpg");
final int splashWidthPx = bgIcon.getIconWidth();
final int splashHeightPx = bgIcon.getIconHeight();
monitor = new MultiPhaseProgressMonitorWithETA("Loading card database", 1,
1, 1.0f);
final JDialog progressBarDialog = monitor.getDialog();
final Rectangle progressRect = progressBarDialog.getBounds();
setMinimumSize(new Dimension(splashWidthPx, splashHeightPx));
setLocation(progressRect.x, progressRect.y + progressRect.height);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
setContentPane(contentPane);
contentPane.setLayout(null);
final JLabel lblDisclaimer = new JLabel("Forge is not affiliated in any way with Wizards of the Coast.");
// we can't do multiline labels.
//+ "\nIt is open source software, released under the GNU Public License."
//+ "\n And while we have your attention, go buy some Magic: the Gathering cards!"
lblDisclaimer.setBounds(DISCLAIMER_EAST_WEST_PADDING_PX, DISCLAIMER_NORTH_PADDING_PX,
splashWidthPx - (2 * DISCLAIMER_EAST_WEST_PADDING_PX),
DISCLAIMER_HEIGHT_PX);
lblDisclaimer.setFont(new Font("Tahoma", Font.PLAIN, DISCLAIMER_FONT_SIZE));
lblDisclaimer.setHorizontalAlignment(SwingConstants.CENTER);
lblDisclaimer.setForeground(WHITE_COLOR);
contentPane.add(lblDisclaimer);
// Add background image.
contentPane.setOpaque(false);
final JLabel bgLabel = new JLabel(bgIcon);
// Do not pass Integer.MIN_VALUE directly here; it must be packaged in an Integer
// instance. Otherwise, GUI components will not draw unless moused over.
getLayeredPane().add(bgLabel, Integer.valueOf(Integer.MIN_VALUE));
bgLabel.setBounds(0, 0, bgIcon.getIconWidth(), bgIcon.getIconHeight());
pack();
}
/**
* Getter for monitor.
* @return the MultiPhaseProgressMonitorWithETA in the lower section of this JFrame
*/
public final MultiPhaseProgressMonitorWithETA getMonitor() {
return monitor;
}
/**
* Setter for monitor.
* @param neoMonitor the MultiPhaseProgressMonitorWithETA in the lower section of this JFrame
*/
protected final void setMonitor(final MultiPhaseProgressMonitorWithETA neoMonitor) {
this.monitor = neoMonitor;
}
}

View File

@@ -1,9 +1,12 @@
package net.slightlymagic.braids.util; package net.slightlymagic.braids.util;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.swing.SwingUtilities;
/** /**
* Some general-purpose functions. * Some general-purpose functions.
*/ */
@@ -39,9 +42,36 @@ public final class UtilFunctions {
exn.setStackTrace(slice(new StackTraceElement[len], trace, 1)); exn.setStackTrace(slice(new StackTraceElement[len], trace, 1));
throw exn; throw exn;
} }
/** /**
* Invoke the given Runnable in an Event Dispatch Thread and wait for it
* to finish; but <B>try to use SwingUtilities.invokeLater instead whenever
* feasible.</B>
*
* Exceptions generated by SwingUtilities.invokeAndWait (if used), are
* rethrown as RuntimeExceptions.
*
* @see javax.swing.SwingUtilities#invokeLater(Runnable)
*
* @param proc the Runnable to run
*/
public static void invokeInEventDispatchThreadAndWait(final Runnable proc) {
if (SwingUtilities.isEventDispatchThread()) {
// Just run in the current thread.
proc.run();
}
else {
try {
SwingUtilities.invokeAndWait(proc);
} catch (InterruptedException exn) {
throw new RuntimeException(exn);
} catch (InvocationTargetException exn) {
throw new RuntimeException(exn);
}
}
}
/**
* Create an array from the (rest of) an iterator's output; * Create an array from the (rest of) an iterator's output;
* this function is horribly inefficient. * this function is horribly inefficient.
* *

View File

@@ -8,6 +8,7 @@ import forge.view.swing.OldGuiNewGame;
import net.slightlymagic.braids.util.ClumsyRunnable; import net.slightlymagic.braids.util.ClumsyRunnable;
import net.slightlymagic.braids.util.testng.BraidsAssertFunctions; import net.slightlymagic.braids.util.testng.BraidsAssertFunctions;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.util.Set; import java.util.Set;
@@ -24,13 +25,14 @@ import java.util.TreeSet;
@Test(groups = {"UnitTest"}, timeOut = 5000) @Test(groups = {"UnitTest"}, timeOut = 5000)
public class CardFactoryTest implements NewConstants { public class CardFactoryTest implements NewConstants {
private static CardFactoryInterface factory; private CardFactoryInterface factory;
static {
@BeforeMethod
public final void setUp() {
OldGuiNewGame.loadDynamicGamedata(); OldGuiNewGame.loadDynamicGamedata();
factory = new LazyCardFactory(ForgeProps.getFile(CARDSFOLDER)); factory = new LazyCardFactory(ForgeProps.getFile(CARDSFOLDER));
} }
/** /**
* Just a quick test to see if Arc-Slogger is in the database, and if it * Just a quick test to see if Arc-Slogger is in the database, and if it
* has the correct owner. * has the correct owner.
@@ -44,10 +46,8 @@ public class CardFactoryTest implements NewConstants {
/** /**
* Make sure the method throws an exception when it's supposed to. * Make sure the method throws an exception when it's supposed to.
*
* This doesn't work with LazyCardFactory, so it is too slow to enable by default.
*/ */
@Test(enabled = false, timeOut = 5000) @Test(enabled = true, timeOut = 5000)
public final void test_getRandomCombinationWithoutRepetition_tooLarge() { public final void test_getRandomCombinationWithoutRepetition_tooLarge() {
BraidsAssertFunctions.assertThrowsException(IllegalArgumentException.class, BraidsAssertFunctions.assertThrowsException(IllegalArgumentException.class,
new ClumsyRunnable() { new ClumsyRunnable() {
@@ -72,6 +72,7 @@ public class CardFactoryTest implements NewConstants {
*/ */
@Test(enabled = false, timeOut = 5000) @Test(enabled = false, timeOut = 5000)
public final void test_getRandomCombinationWithoutRepetition_oneTenth() { public final void test_getRandomCombinationWithoutRepetition_oneTenth() {
factory = new PreloadingCardFactory(ForgeProps.getFile(CARDSFOLDER));
int divisor = 10; int divisor = 10;
final CardList actual = factory.getRandomCombinationWithoutRepetition(factory.size() / divisor); final CardList actual = factory.getRandomCombinationWithoutRepetition(factory.size() / divisor);