Chris@1407: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@1407: Chris@1407: /* Chris@1407: Sonic Visualiser Chris@1407: An audio file viewer and annotation editor. Chris@1407: Centre for Digital Music, Queen Mary, University of London. Chris@1407: Chris@1407: This program is free software; you can redistribute it and/or Chris@1407: modify it under the terms of the GNU General Public License as Chris@1407: published by the Free Software Foundation; either version 2 of the Chris@1407: License, or (at your option) any later version. See the file Chris@1407: COPYING included with this distribution for more information. Chris@1407: */ Chris@1407: Chris@1407: #ifndef TEST_SCALE_TICK_INTERVALS_H Chris@1407: #define TEST_SCALE_TICK_INTERVALS_H Chris@1407: Chris@1407: #include "../ScaleTickIntervals.h" Chris@1407: Chris@1407: #include Chris@1407: #include Chris@1407: #include Chris@1407: Chris@1407: #include Chris@1407: Chris@1407: using namespace std; Chris@1407: Chris@1407: class TestScaleTickIntervals : public QObject Chris@1407: { Chris@1407: Q_OBJECT Chris@1407: Chris@1407: void printDiff(vector ticks, Chris@1407: vector expected) { Chris@1407: Chris@1407: cerr << "Have " << ticks.size() << " ticks, expected " Chris@1407: << expected.size() << endl; Chris@1411: for (int i = 0; i < int(ticks.size()); ++i) { Chris@1411: cerr << i << ": have " << ticks[i].value << " \"" Chris@1411: << ticks[i].label << "\", expected "; Chris@1411: if (i < int(expected.size())) { Chris@1411: cerr << expected[i].value << " \"" << expected[i].label Chris@1407: << "\"" << endl; Chris@1411: } else { Chris@1411: cerr << "(n/a)" << endl; Chris@1407: } Chris@1407: } Chris@1407: } Chris@1407: Chris@1407: void compareTicks(vector ticks, Chris@1415: vector expected, Chris@1415: bool fuzzier = false) Chris@1407: { Chris@1408: double eps = 1e-7; Chris@1407: for (int i = 0; i < int(expected.size()); ++i) { Chris@1407: if (i < int(ticks.size())) { Chris@1415: bool pass = true; Chris@1415: if (ticks[i].label != expected[i].label) { Chris@1415: pass = false; Chris@1415: } else if (!fuzzier) { Chris@1415: if (fabs(ticks[i].value - expected[i].value) > eps) { Chris@1415: pass = false; Chris@1415: } Chris@1415: } else { Chris@1415: if (fabs(ticks[i].value - expected[i].value) > Chris@1415: fabs(ticks[i].value) * 1e-5) { Chris@1415: pass = false; Chris@1415: } Chris@1415: } Chris@1415: if (!pass) { Chris@1407: printDiff(ticks, expected); Chris@1415: QCOMPARE(ticks[i].label, expected[i].label); Chris@1415: QCOMPARE(ticks[i].value, expected[i].value); Chris@1415: } Chris@1407: } Chris@1407: } Chris@1408: if (ticks.size() != expected.size()) { Chris@1408: printDiff(ticks, expected); Chris@1408: } Chris@1407: QCOMPARE(ticks.size(), expected.size()); Chris@1407: } Chris@1407: Chris@1407: private slots: Chris@1407: void linear_0_1_10() Chris@1407: { Chris@1407: auto ticks = ScaleTickIntervals::linear({ 0, 1, 10 }); Chris@1407: vector expected { Chris@1409: { 0.0, "0.0" }, Chris@1409: { 0.1, "0.1" }, Chris@1409: { 0.2, "0.2" }, Chris@1409: { 0.3, "0.3" }, Chris@1409: { 0.4, "0.4" }, Chris@1409: { 0.5, "0.5" }, Chris@1409: { 0.6, "0.6" }, Chris@1409: { 0.7, "0.7" }, Chris@1409: { 0.8, "0.8" }, Chris@1409: { 0.9, "0.9" }, Chris@1409: { 1.0, "1.0" } Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1409: void linear_0_5_5() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ 0, 5, 5 }); Chris@1409: vector expected { Chris@1415: { 0, "0" }, Chris@1415: { 1, "1" }, Chris@1415: { 2, "2" }, Chris@1415: { 3, "3" }, Chris@1415: { 4, "4" }, Chris@1415: { 5, "5" }, Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1409: void linear_0_10_5() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ 0, 10, 5 }); Chris@1409: vector expected { Chris@1415: { 0, "0" }, Chris@1415: { 2, "2" }, Chris@1415: { 4, "4" }, Chris@1415: { 6, "6" }, Chris@1415: { 8, "8" }, Chris@1415: { 10, "10" } Chris@1407: }; Chris@1407: compareTicks(ticks.ticks, expected); Chris@1407: } Chris@1407: Chris@1411: void linear_10_0_5() Chris@1411: { Chris@1411: auto ticks = ScaleTickIntervals::linear({ 10, 0, 5 }); Chris@1411: vector expected { Chris@1415: { 0, "0" }, Chris@1415: { 2, "2" }, Chris@1415: { 4, "4" }, Chris@1415: { 6, "6" }, Chris@1415: { 8, "8" }, Chris@1415: { 10, "10" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_m10_0_5() Chris@1411: { Chris@1411: auto ticks = ScaleTickIntervals::linear({ -10, 0, 5 }); Chris@1411: vector expected { Chris@1415: { -10, "-10" }, Chris@1415: { -8, "-8" }, Chris@1415: { -6, "-6" }, Chris@1415: { -4, "-4" }, Chris@1415: { -2, "-2" }, Chris@1415: { 0, "0" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_0_m10_5() Chris@1411: { Chris@1411: auto ticks = ScaleTickIntervals::linear({ 0, -10, 5 }); Chris@1411: vector expected { Chris@1415: { -10, "-10" }, Chris@1415: { -8, "-8" }, Chris@1415: { -6, "-6" }, Chris@1415: { -4, "-4" }, Chris@1415: { -2, "-2" }, Chris@1415: { 0, "0" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1407: void linear_0_0p1_5() Chris@1407: { Chris@1407: auto ticks = ScaleTickIntervals::linear({ 0, 0.1, 5 }); Chris@1407: vector expected { Chris@1409: { 0.00, "0.00" }, Chris@1407: { 0.02, "0.02" }, Chris@1407: { 0.04, "0.04" }, Chris@1407: { 0.06, "0.06" }, Chris@1407: { 0.08, "0.08" }, Chris@1409: { 0.10, "0.10" } Chris@1407: }; Chris@1407: compareTicks(ticks.ticks, expected); Chris@1407: } Chris@1407: Chris@1407: void linear_0_0p01_5() Chris@1407: { Chris@1407: auto ticks = ScaleTickIntervals::linear({ 0, 0.01, 5 }); Chris@1407: vector expected { Chris@1409: { 0.000, "0.000" }, Chris@1407: { 0.002, "0.002" }, Chris@1407: { 0.004, "0.004" }, Chris@1407: { 0.006, "0.006" }, Chris@1407: { 0.008, "0.008" }, Chris@1409: { 0.010, "0.010" } Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1409: void linear_0_0p005_5() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ 0, 0.005, 5 }); Chris@1409: vector expected { Chris@1409: { 0.000, "0.000" }, Chris@1409: { 0.001, "0.001" }, Chris@1409: { 0.002, "0.002" }, Chris@1409: { 0.003, "0.003" }, Chris@1409: { 0.004, "0.004" }, Chris@1409: { 0.005, "0.005" } Chris@1407: }; Chris@1407: compareTicks(ticks.ticks, expected); Chris@1407: } Chris@1407: Chris@1407: void linear_0_0p001_5() Chris@1407: { Chris@1407: auto ticks = ScaleTickIntervals::linear({ 0, 0.001, 5 }); Chris@1407: vector expected { Chris@1409: { 0.0000, "0.0e+00" }, Chris@1407: { 0.0002, "2.0e-04" }, Chris@1407: { 0.0004, "4.0e-04" }, Chris@1407: { 0.0006, "6.0e-04" }, Chris@1407: { 0.0008, "8.0e-04" }, Chris@1409: { 0.0010, "1.0e-03" } Chris@1407: }; Chris@1407: compareTicks(ticks.ticks, expected); Chris@1407: } Chris@1407: Chris@1407: void linear_1_1p001_5() Chris@1407: { Chris@1407: auto ticks = ScaleTickIntervals::linear({ 1, 1.001, 5 }); Chris@1407: vector expected { Chris@1409: { 1.0000, "1.0000" }, Chris@1407: { 1.0002, "1.0002" }, Chris@1407: { 1.0004, "1.0004" }, Chris@1407: { 1.0006, "1.0006" }, Chris@1407: { 1.0008, "1.0008" }, Chris@1409: { 1.0010, "1.0010" } Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1413: void linear_0p001_1_5() Chris@1413: { Chris@1413: auto ticks = ScaleTickIntervals::linear({ 0.001, 1, 5 }); Chris@1413: vector expected { Chris@1413: { 0.1, "0.1" }, Chris@1413: { 0.3, "0.3" }, Chris@1413: { 0.5, "0.5" }, Chris@1413: { 0.7, "0.7" }, Chris@1413: { 0.9, "0.9" }, Chris@1413: }; Chris@1413: compareTicks(ticks.ticks, expected); Chris@1413: } Chris@1413: Chris@1409: void linear_10000_10010_5() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ 10000, 10010, 5 }); Chris@1409: vector expected { Chris@1415: { 10000, "10000" }, Chris@1415: { 10002, "10002" }, Chris@1415: { 10004, "10004" }, Chris@1415: { 10006, "10006" }, Chris@1415: { 10008, "10008" }, Chris@1415: { 10010, "10010" }, Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1409: void linear_10000_20000_5() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ 10000, 20000, 5 }); Chris@1409: vector expected { Chris@1409: { 10000, "10000" }, Chris@1409: { 12000, "12000" }, Chris@1409: { 14000, "14000" }, Chris@1409: { 16000, "16000" }, Chris@1409: { 18000, "18000" }, Chris@1409: { 20000, "20000" }, Chris@1409: }; Chris@1409: compareTicks(ticks.ticks, expected); Chris@1409: } Chris@1409: Chris@1409: void linear_m1_1_10() Chris@1409: { Chris@1409: auto ticks = ScaleTickIntervals::linear({ -1, 1, 10 }); Chris@1409: vector expected { Chris@1409: { -1.0, "-1.0" }, Chris@1409: { -0.8, "-0.8" }, Chris@1409: { -0.6, "-0.6" }, Chris@1409: { -0.4, "-0.4" }, Chris@1409: { -0.2, "-0.2" }, Chris@1409: { 0.0, "0.0" }, Chris@1409: { 0.2, "0.2" }, Chris@1409: { 0.4, "0.4" }, Chris@1409: { 0.6, "0.6" }, Chris@1409: { 0.8, "0.8" }, Chris@1409: { 1.0, "1.0" } Chris@1407: }; Chris@1407: compareTicks(ticks.ticks, expected); Chris@1407: } Chris@1411: Chris@1411: void linear_221p23_623p7_57p4() Chris@1411: { Chris@1411: auto ticks = ScaleTickIntervals::linear({ 221.23, 623.7, 4 }); Chris@1411: // only 4 ticks, not 5, because none of the rounded tick Chris@1411: // values lies on an end value Chris@1411: vector expected { Chris@1411: { 230, "230" }, Chris@1411: { 330, "330" }, Chris@1411: { 430, "430" }, Chris@1411: { 530, "530" }, Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1412: void linear_sqrt2_pi_7() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ sqrt(2.0), M_PI, 7 }); Chris@1412: // This would be better in steps of 0.25, but we only round to Chris@1412: // integral powers of ten Chris@1412: vector expected { Chris@1412: { 1.5, "1.5" }, Chris@1412: { 1.7, "1.7" }, Chris@1412: { 1.9, "1.9" }, Chris@1412: { 2.1, "2.1" }, Chris@1412: { 2.3, "2.3" }, Chris@1412: { 2.5, "2.5" }, Chris@1412: { 2.7, "2.7" }, Chris@1412: { 2.9, "2.9" }, Chris@1412: { 3.1, "3.1" }, Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_pi_avogadro_7() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ M_PI, 6.022140857e23, 7 }); Chris@1412: vector expected { Chris@1413: { 1e+21, "1.000e+21" }, Chris@1413: { 8.7e+22, "8.700e+22" }, Chris@1413: { 1.73e+23, "1.730e+23" }, Chris@1413: { 2.59e+23, "2.590e+23" }, Chris@1413: { 3.45e+23, "3.450e+23" }, Chris@1413: { 4.31e+23, "4.310e+23" }, Chris@1413: { 5.17e+23, "5.170e+23" }, Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_1() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 1 }); Chris@1412: vector expected { Chris@1415: { 2.0, "2" }, Chris@1415: { 3.0, "3" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_2() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 2 }); Chris@1412: vector expected { Chris@1412: { 2.0, "2.0" }, Chris@1412: { 2.5, "2.5" }, Chris@1412: { 3.0, "3.0" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_3() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 3 }); Chris@1412: vector expected { Chris@1412: { 2.0, "2.0" }, Chris@1412: { 2.3, "2.3" }, Chris@1412: { 2.6, "2.6" }, Chris@1412: { 2.9, "2.9" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_4() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 4 }); Chris@1412: // This would be better in steps of 0.25, but we only round to Chris@1412: // integral powers of ten Chris@1412: vector expected { Chris@1412: { 2.0, "2.0" }, Chris@1412: { 2.3, "2.3" }, Chris@1412: { 2.6, "2.6" }, Chris@1412: { 2.9, "2.9" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_5() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 5 }); Chris@1412: vector expected { Chris@1412: { 2.0, "2.0" }, Chris@1412: { 2.2, "2.2" }, Chris@1412: { 2.4, "2.4" }, Chris@1412: { 2.6, "2.6" }, Chris@1412: { 2.8, "2.8" }, Chris@1412: { 3.0, "3.0" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1412: void linear_2_3_6() Chris@1412: { Chris@1412: auto ticks = ScaleTickIntervals::linear({ 2, 3, 6 }); Chris@1412: vector expected { Chris@1412: { 2.0, "2.0" }, Chris@1412: { 2.2, "2.2" }, Chris@1412: { 2.4, "2.4" }, Chris@1412: { 2.6, "2.6" }, Chris@1412: { 2.8, "2.8" }, Chris@1412: { 3.0, "3.0" } Chris@1412: }; Chris@1412: compareTicks(ticks.ticks, expected); Chris@1412: } Chris@1412: Chris@1411: void linear_1_1_10() Chris@1411: { Chris@1415: // pathological range Chris@1411: auto ticks = ScaleTickIntervals::linear({ 1, 1, 10 }); Chris@1411: vector expected { Chris@1411: { 1.0, "1.0" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_0_0_10() Chris@1411: { Chris@1415: // pathological range Chris@1411: auto ticks = ScaleTickIntervals::linear({ 0, 0, 10 }); Chris@1411: vector expected { Chris@1411: { 0.0, "0.0" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_0_1_1() Chris@1411: { Chris@1411: auto ticks = ScaleTickIntervals::linear({ 0, 1, 1 }); Chris@1411: vector expected { Chris@1415: { 0.0, "0" }, Chris@1415: { 1.0, "1" } Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_0_1_0() Chris@1411: { Chris@1416: // senseless input Chris@1411: auto ticks = ScaleTickIntervals::linear({ 0, 1, 0 }); Chris@1411: vector expected { Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1411: Chris@1411: void linear_0_1_m1() Chris@1411: { Chris@1416: // senseless input Chris@1411: auto ticks = ScaleTickIntervals::linear({ 0, 1, -1 }); Chris@1411: vector expected { Chris@1411: }; Chris@1411: compareTicks(ticks.ticks, expected); Chris@1411: } Chris@1414: Chris@1416: void linear_0p465_778_10() Chris@1416: { Chris@1416: // a case that gave unsatisfactory results in real life Chris@1416: auto ticks = ScaleTickIntervals::linear({ 0.465, 778.08, 10 }); Chris@1416: vector expected { Chris@1416: }; Chris@1416: compareTicks(ticks.ticks, expected); Chris@1416: } Chris@1416: Chris@1414: void log_1_10_2() Chris@1414: { Chris@1414: auto ticks = ScaleTickIntervals::logarithmic({ 1, 10, 2 }); Chris@1414: vector expected { Chris@1414: { 1.0, "1.0" }, Chris@1414: { pow(10.0, 0.5), "3.2" }, Chris@1414: { 10.0, "10.0" }, Chris@1414: }; Chris@1414: compareTicks(ticks.ticks, expected); Chris@1414: } Chris@1414: Chris@1414: void log_0_10_2() Chris@1414: { Chris@1414: auto ticks = ScaleTickIntervals::logarithmic({ 0, 10, 2 }); Chris@1414: vector expected { Chris@1415: { 1e-10, "1e-10" }, Chris@1415: { pow(10.0, -4.5), "3e-05" }, Chris@1415: { 10.0, "1e+01" }, Chris@1414: }; Chris@1414: compareTicks(ticks.ticks, expected); Chris@1414: } Chris@1415: Chris@1415: void log_pi_avogadro_7() Chris@1415: { Chris@1415: auto ticks = ScaleTickIntervals::logarithmic({ M_PI, 6.022140857e23, 7 }); Chris@1415: vector expected { Chris@1415: { 3.16228, "3e+00" }, Chris@1415: { 6309.57, "6e+03" }, Chris@1415: { 1.25893e+07, "1e+07" }, Chris@1415: { 2.51189e+10, "3e+10" }, Chris@1415: { 5.01187e+13, "5e+13" }, Chris@1415: { 1e+17, "1e+17" }, Chris@1415: { 1.99526e+20, "2e+20" }, Chris@1415: { 3.98107e+23, "4e+23" }, Chris@1415: }; Chris@1415: compareTicks(ticks.ticks, expected, true); Chris@1415: } Chris@1407: }; Chris@1407: Chris@1407: #endif Chris@1407: Chris@1407: