language selector, bug fixed
[debian/openrocket] / test / net / sf / openrocket / IntegrationTest.java
1 package net.sf.openrocket;
2
3 import static org.junit.Assert.*;
4
5 import java.awt.event.ActionEvent;
6 import java.io.IOException;
7 import java.io.InputStream;
8
9 import javax.swing.Action;
10
11 import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
12 import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
13 import net.sf.openrocket.aerodynamics.FlightConditions;
14 import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
15 import net.sf.openrocket.document.OpenRocketDocument;
16 import net.sf.openrocket.document.Simulation;
17 import net.sf.openrocket.file.GeneralRocketLoader;
18 import net.sf.openrocket.file.RocketLoadException;
19 import net.sf.openrocket.file.motor.GeneralMotorLoader;
20 import net.sf.openrocket.l10n.ResourceBundleTranslator;
21 import net.sf.openrocket.masscalc.BasicMassCalculator;
22 import net.sf.openrocket.masscalc.MassCalculator;
23 import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
24 import net.sf.openrocket.motor.Motor;
25 import net.sf.openrocket.motor.ThrustCurveMotor;
26 import net.sf.openrocket.rocketcomponent.Configuration;
27 import net.sf.openrocket.rocketcomponent.EngineBlock;
28 import net.sf.openrocket.rocketcomponent.MassComponent;
29 import net.sf.openrocket.rocketcomponent.NoseCone;
30 import net.sf.openrocket.rocketcomponent.RocketComponent;
31 import net.sf.openrocket.simulation.FlightDataType;
32 import net.sf.openrocket.simulation.exception.SimulationException;
33 import net.sf.openrocket.startup.Application;
34 import net.sf.openrocket.util.Coordinate;
35
36 import org.junit.BeforeClass;
37 import org.junit.Test;
38
39 /**
40  * This class contains various integration tests that simulate user actions that
41  * might be performed.
42  */
43 public class IntegrationTest {
44         
45         private OpenRocketDocument document;
46         private Action undoAction, redoAction;
47         
48         private AerodynamicCalculator aeroCalc = new BarrowmanCalculator();
49         private MassCalculator massCalc = new BasicMassCalculator();
50         private Configuration config;
51         private FlightConditions conditions;
52         
53         
54         @BeforeClass
55         public static void initialize() {
56                 ThrustCurveMotorSetDatabase db = new ThrustCurveMotorSetDatabase(false) {
57                         @Override
58                         protected void loadMotors() {
59                                 GeneralMotorLoader loader = new GeneralMotorLoader();
60                                 InputStream is = this.getClass().getResourceAsStream("Estes_A8.rse");
61                                 assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is);
62                                 try {
63                                         for (Motor m : loader.load(is, "Estes_A8.rse")) {
64                                                 addMotor((ThrustCurveMotor) m);
65                                         }
66                                         is.close();
67                                 } catch (IOException e) {
68                                         e.printStackTrace();
69                                         fail("IOException: " + e);
70                                 }
71                         }
72                 };
73                 db.startLoading();
74                 assertEquals(1, db.getMotorSets().size());
75                 Application.setMotorSetDatabase(db);
76                 Application.setBaseTranslator(new ResourceBundleTranslator("l10n.messages"));
77         }
78         
79         /**
80          * Tests loading a rocket design, modifying it, simulating it and the undo/redo
81          * mechanism in various combinations.
82          */
83         @Test
84         public void test1() throws RocketLoadException, IOException, SimulationException {
85                 System.setProperty("openrocket.unittest", "true");
86                 
87                 // Load the rocket
88                 GeneralRocketLoader loader = new GeneralRocketLoader();
89                 InputStream is = this.getClass().getResourceAsStream("simplerocket.ork");
90                 assertNotNull("Problem in unit test, cannot find simplerocket.ork", is);
91                 document = loader.load(is);
92                 is.close();
93                 
94                 undoAction = document.getUndoAction();
95                 redoAction = document.getRedoAction();
96                 config = document.getSimulation(0).getConfiguration();
97                 conditions = new FlightConditions(config);
98                 
99
100                 // Test undo state
101                 checkUndoState(null, null);
102                 
103
104                 // Compute cg+cp + altitude
105                 checkCgCp(0.248, 0.0645, 0.320, 12.0);
106                 checkAlt(48.2);
107                 
108
109                 // Mass modification
110                 document.addUndoPosition("Modify mass");
111                 checkUndoState(null, null);
112                 massComponent().setComponentMass(0.01);
113                 checkUndoState("Modify mass", null);
114                 
115
116                 // Check cg+cp + altitude
117                 checkCgCp(0.230, 0.0745, 0.320, 12.0);
118                 checkAlt(37.2);
119                 
120
121                 // Non-change
122                 document.addUndoPosition("No change");
123                 checkUndoState("Modify mass", null);
124                 
125
126                 // Non-funcitonal change
127                 document.addUndoPosition("Name change");
128                 checkUndoState("Modify mass", null);
129                 massComponent().setName("Foobar component");
130                 checkUndoState("Name change", null);
131                 
132
133                 // Check cg+cp
134                 checkCgCp(0.230, 0.0745, 0.320, 12.0);
135                 
136
137                 // Aerodynamic modification
138                 document.addUndoPosition("Remove component");
139                 checkUndoState("Name change", null);
140                 document.getRocket().getChild(0).removeChild(0);
141                 checkUndoState("Remove component", null);
142                 
143
144                 // Check cg+cp + altitude
145                 checkCgCp(0.163, 0.0613, 0.275, 9.95);
146                 checkAlt(45.0);
147                 
148
149                 // Undo "Remove component" change
150                 undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
151                 assertTrue(document.getRocket().getChild(0).getChild(0) instanceof NoseCone);
152                 checkUndoState("Name change", "Remove component");
153                 
154
155                 // Check cg+cp + altitude
156                 checkCgCp(0.230, 0.0745, 0.320, 12.0);
157                 checkAlt(37.2);
158                 
159
160                 // Undo "Name change" change
161                 undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
162                 assertEquals("Extra mass", massComponent().getName());
163                 checkUndoState("Modify mass", "Name change");
164                 
165
166                 // Check cg+cp
167                 checkCgCp(0.230, 0.0745, 0.320, 12.0);
168                 
169
170                 // Undo "Modify mass" change
171                 undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
172                 assertEquals(0, massComponent().getComponentMass(), 0);
173                 checkUndoState(null, "Modify mass");
174                 
175
176                 // Check cg+cp + altitude
177                 checkCgCp(0.248, 0.0645, 0.320, 12.0);
178                 checkAlt(48.2);
179                 
180
181                 // Redo "Modify mass" change
182                 redoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
183                 assertEquals(0.010, massComponent().getComponentMass(), 0.00001);
184                 checkUndoState("Modify mass", "Name change");
185                 
186
187                 // Check cg+cp + altitude
188                 checkCgCp(0.230, 0.0745, 0.320, 12.0);
189                 checkAlt(37.2);
190                 
191
192                 // Mass modification
193                 document.addUndoPosition("Modify mass2");
194                 checkUndoState("Modify mass", "Name change");
195                 massComponent().setComponentMass(0.015);
196                 checkUndoState("Modify mass2", null);
197                 
198
199                 // Check cg+cp + altitude
200                 checkCgCp(0.223, 0.0795, 0.320, 12.0);
201                 checkAlt(32.7);
202                 
203
204                 // Perform component movement
205                 document.startUndo("Move component");
206                 document.getRocket().freeze();
207                 RocketComponent bodytube = document.getRocket().getChild(0).getChild(1);
208                 RocketComponent innertube = bodytube.getChild(2);
209                 RocketComponent engineblock = innertube.getChild(0);
210                 assertTrue(innertube.removeChild(engineblock));
211                 bodytube.addChild(engineblock, 0);
212                 checkUndoState("Modify mass2", null);
213                 document.getRocket().thaw();
214                 checkUndoState("Move component", null);
215                 document.stopUndo();
216                 
217
218                 // Check cg+cp + altitude
219                 checkCgCp(0.221, 0.0797, 0.320, 12.0);
220                 checkAlt(32.7);
221                 
222
223                 // Modify mass without setting undo description
224                 massComponent().setComponentMass(0.020);
225                 checkUndoState("Modify mass2", null);
226                 
227
228                 // Check cg+cp + altitude
229                 checkCgCp(0.215, 0.0847, 0.320, 12.0);
230                 checkAlt(29.0);
231                 
232
233                 // Undo "Modify mass2" change
234                 undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
235                 assertEquals(0.015, massComponent().getComponentMass(), 0.0000001);
236                 checkUndoState("Move component", "Modify mass2");
237                 
238
239                 // Check cg+cp + altitude
240                 checkCgCp(0.221, 0.0797, 0.320, 12.0);
241                 checkAlt(32.7);
242                 
243
244                 // Undo "Move component" change
245                 undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
246                 assertTrue(document.getRocket().getChild(0).getChild(1).getChild(2).getChild(0) instanceof EngineBlock);
247                 checkUndoState("Modify mass2", "Move component");
248                 
249
250                 // Check cg+cp + altitude
251                 checkCgCp(0.223, 0.0795, 0.320, 12.0);
252                 checkAlt(32.7);
253                 
254
255                 // Redo "Move component" change
256                 redoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
257                 assertTrue(document.getRocket().getChild(0).getChild(1).getChild(0) instanceof EngineBlock);
258                 checkUndoState("Move component", "Modify mass2");
259                 
260
261                 // Check cg+cp + altitude
262                 checkCgCp(0.221, 0.0797, 0.320, 12.0);
263                 checkAlt(32.7);
264                 
265
266         }
267         
268         private String massComponentID = null;
269         
270         private MassComponent massComponent() {
271                 if (massComponentID == null) {
272                         massComponentID = document.getRocket().getChild(0).getChild(1).getChild(0).getID();
273                 }
274                 return (MassComponent) document.getRocket().findComponent(massComponentID);
275         }
276         
277         
278         private void checkUndoState(String undoDesc, String redoDesc) {
279                 if (undoDesc == null) {
280                         assertEquals("Undo", undoAction.getValue(Action.NAME));
281                         assertFalse(undoAction.isEnabled());
282                 } else {
283                         assertEquals("Undo (" + undoDesc + ")", undoAction.getValue(Action.NAME));
284                         assertTrue(undoAction.isEnabled());
285                 }
286                 if (redoDesc == null) {
287                         assertEquals("Redo", redoAction.getValue(Action.NAME));
288                         assertFalse(redoAction.isEnabled());
289                 } else {
290                         assertEquals("Redo (" + redoDesc + ")", redoAction.getValue(Action.NAME));
291                         assertTrue(redoAction.isEnabled());
292                 }
293         }
294         
295         
296         private void checkCgCp(double cgx, double mass, double cpx, double cna) {
297                 Coordinate cg, cp;
298                 
299                 cg = massCalc.getCG(config, MassCalcType.LAUNCH_MASS);
300                 assertEquals(cgx, cg.x, 0.001);
301                 assertEquals(mass, cg.weight, 0.0005);
302                 
303                 cp = aeroCalc.getWorstCP(config, conditions, null);
304                 assertEquals(cpx, cp.x, 0.001);
305                 assertEquals(cna, cp.weight, 0.1);
306         }
307         
308         
309         private void checkAlt(double expected) throws SimulationException {
310                 Simulation simulation = document.getSimulation(0);
311                 double actual;
312                 
313                 // Simulate + check altitude
314                 simulation.simulate();
315                 actual = simulation.getSimulatedData().getBranch(0).getMaximum(FlightDataType.TYPE_ALTITUDE);
316                 assertEquals(expected, actual, 0.5);
317         }
318         
319 }