summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--dive.c14
-rw-r--r--dive.h1
-rw-r--r--planner.c1
-rw-r--r--planner.h1
-rw-r--r--tests/testplan.cpp119
-rw-r--r--tests/testplan.h13
7 files changed, 148 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 534e8e2b6..5f6d1fb24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -520,6 +520,7 @@ if(NOT NO_TESTS)
TEST(TestProfile testprofile.cpp)
TEST(TestGpsCoords testgpscoords.cpp)
TEST(TestParse testparse.cpp)
+ TEST(TestPlan testplan.cpp)
endif()
# install a few things so that one can run Subsurface from the build
diff --git a/dive.c b/dive.c
index aadddfd14..8aac690a3 100644
--- a/dive.c
+++ b/dive.c
@@ -3119,3 +3119,17 @@ void delete_current_divecomputer(void)
if (dc_number == count_divecomputers())
dc_number--;
}
+
+/* helper function to make it easier to work with our structures
+ * we don't interpolate here, just use the value from the last sample up to that time */
+int get_depth_at_time(struct divecomputer *dc, int time)
+{
+ int depth = 0;
+ if (dc && dc->sample)
+ for (int i = 0; i < dc->samples; i++) {
+ if (dc->sample[i].time.seconds > time)
+ break;
+ depth = dc->sample[i].depth.mm;
+ }
+ return depth;
+}
diff --git a/dive.h b/dive.h
index 042878c1b..9019511d1 100644
--- a/dive.h
+++ b/dive.h
@@ -393,6 +393,7 @@ extern timestamp_t picture_get_timestamp(char *filename);
extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic);
extern int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc);
+extern int get_depth_at_time(struct divecomputer *dc, int time);
static inline int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null)
{
diff --git a/planner.c b/planner.c
index 507cea03a..fcca0d78e 100644
--- a/planner.c
+++ b/planner.c
@@ -857,7 +857,6 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
int bottom_depth;
int bottom_gi;
int bottom_stopidx;
-
bool is_final_plan = true;
int deco_time;
int previous_deco_time;
diff --git a/planner.h b/planner.h
index 9a2c08b3d..ac146055d 100644
--- a/planner.h
+++ b/planner.h
@@ -11,7 +11,6 @@ extern "C" {
extern int validate_gas(const char *text, struct gasmix *gas);
extern int validate_po2(const char *text, int *mbar_po2);
extern timestamp_t current_time_notz(void);
-extern void show_planned_dive(char **error_string_p);
extern void set_last_stop(bool last_stop_6m);
extern void set_verbatim(bool verbatim);
extern void set_display_runtime(bool display);
diff --git a/tests/testplan.cpp b/tests/testplan.cpp
new file mode 100644
index 000000000..f08cfdeeb
--- /dev/null
+++ b/tests/testplan.cpp
@@ -0,0 +1,119 @@
+#include "dive.h"
+#include "testplan.h"
+#include "planner.h"
+#include "units.h"
+#include <QDebug>
+
+// testing the dive plan algorithm
+extern bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool show_disclaimer);
+
+void setupPrefs()
+{
+ prefs = default_prefs;
+ prefs.ascrate50 = feet_to_mm(30) / 60;
+ prefs.ascrate75 = prefs.ascrate50;
+ prefs.ascratestops = prefs.ascrate50;
+ prefs.ascratelast6m = feet_to_mm(10) / 60;
+ prefs.last_stop = true;
+
+}
+
+void setupPlan(struct diveplan *dp)
+{
+ dp->salinity = 10030;
+ dp->surface_pressure = 1013;
+ dp->gfhigh = 100;
+ dp->gflow = 100;
+ dp->bottomsac = 0;
+ dp->decosac = 0;
+
+ struct gasmix bottomgas = { {150}, {450} };
+ struct gasmix ean36 = { {360}, {0} };
+ struct gasmix oxygen = { {1000}, {0} };
+ pressure_t po2 = { 1600 };
+ displayed_dive.cylinder[0].gasmix = bottomgas;
+ displayed_dive.cylinder[1].gasmix = ean36;
+ displayed_dive.cylinder[2].gasmix = oxygen;
+ reset_cylinders(&displayed_dive, true);
+ free_dps(dp);
+
+ int droptime = M_OR_FT(79, 260) * 60 / M_OR_FT(23, 75);
+ plan_add_segment(dp, droptime, M_OR_FT(79, 260), bottomgas, 0, 1);
+ plan_add_segment(dp, 30*60 - droptime, M_OR_FT(79, 260), bottomgas, 0, 1);
+ plan_add_segment(dp, 0, gas_mod(&ean36, po2, M_OR_FT(3,10)).mm, ean36, 0, 1);
+ plan_add_segment(dp, 0, gas_mod(&oxygen, po2, M_OR_FT(3,10)).mm, oxygen, 0, 1);
+}
+
+void TestPlan::testMetric()
+{
+ char *cache = NULL;
+
+ setupPrefs();
+ prefs.unit_system = METRIC;
+ prefs.units.length = units::METERS;
+ prefs.deco_mode = BUEHLMANN;
+
+ struct diveplan testPlan = { 0 };
+ setupPlan(&testPlan);
+
+ plan(&testPlan, &cache, 1, 0);
+
+#if DEBUG
+ free(displayed_dive.notes);
+ displayed_dive.notes = NULL;
+ save_dive(stdout, &displayed_dive);
+#endif
+
+ // check first gas change to EAN36 at 33m
+ struct event *ev = displayed_dive.dc.events;
+ QVERIFY(ev != NULL);
+ QCOMPARE(ev->gas.index, 1);
+ QCOMPARE(ev->value, 36);
+ QCOMPARE(get_depth_at_time(&displayed_dive.dc, ev->time.seconds), 33000);
+ // check second gas change to Oxygen at 6m
+ ev = ev->next;
+ QVERIFY(ev != NULL);
+ QCOMPARE(ev->gas.index, 2);
+ QCOMPARE(ev->value, 100);
+ QCOMPARE(get_depth_at_time(&displayed_dive.dc, ev->time.seconds), 6000);
+ // check expected run time of 105 minutes
+ QCOMPARE(displayed_dive.dc.duration.seconds, 104u * 60u);
+}
+
+void TestPlan::testImperial()
+{
+ char *cache = NULL;
+
+ setupPrefs();
+ prefs.unit_system = IMPERIAL;
+ prefs.units.length = units::FEET;
+ prefs.deco_mode = BUEHLMANN;
+
+ struct diveplan testPlan = { 0 };
+ setupPlan(&testPlan);
+
+ plan(&testPlan, &cache, 1, 0);
+
+#if DEBUG
+ free(displayed_dive.notes);
+ displayed_dive.notes = NULL;
+ save_dive(stdout, &displayed_dive);
+#endif
+
+ // check first gas change to EAN36 at 33m
+ struct event *ev = displayed_dive.dc.events;
+ QVERIFY(ev != NULL);
+ QCOMPARE(ev->gas.index, 1);
+ QCOMPARE(ev->value, 36);
+ QCOMPARE(get_depth_at_time(&displayed_dive.dc, ev->time.seconds), 33528);
+ // check second gas change to Oxygen at 6m
+ ev = ev->next;
+ QVERIFY(ev != NULL);
+ QCOMPARE(ev->gas.index, 2);
+ QCOMPARE(ev->value, 100);
+ QCOMPARE(get_depth_at_time(&displayed_dive.dc, ev->time.seconds), 6096);
+ // check expected run time of 105 minutes
+ QCOMPARE(displayed_dive.dc.duration.seconds, 105u * 60u);
+}
+
+QTEST_MAIN(TestPlan)
diff --git a/tests/testplan.h b/tests/testplan.h
new file mode 100644
index 000000000..b35cd75c6
--- /dev/null
+++ b/tests/testplan.h
@@ -0,0 +1,13 @@
+#ifndef TESTPLAN_H
+#define TESTPLAN_H
+
+#include <QTest>
+
+class TestPlan : public QObject {
+ Q_OBJECT
+private slots:
+ void testImperial();
+ void testMetric();
+};
+
+#endif // TESTPLAN_H