Avoid potential negative array index access to cached text.
[LibreOffice.git] / sc / qa / unit / ucalc_solver.cxx
blob7834597e9c070fd96fe19e8e72e9bbccc4237e8a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
11 #include "helper/qahelper.hxx"
12 #include <document.hxx>
13 #include <docfunc.hxx>
14 #include <table.hxx>
15 #include <SolverSettings.hxx>
17 using namespace sc;
19 class SolverTest : public ScModelTestBase
21 public:
22 SolverTest()
23 : ScModelTestBase("sc/qa/unit/data")
27 std::vector<ModelConstraint> CreateConstraintsModelA();
28 void TestConstraintsModelA(SolverSettings* pSettings);
31 // Creates a simple set of constraints for testing
32 std::vector<ModelConstraint> SolverTest::CreateConstraintsModelA()
34 std::vector<ModelConstraint> aConstraints;
36 ModelConstraint aConstr1;
37 aConstr1.aLeftStr = "C1:C10";
38 aConstr1.nOperator = CO_LESS_EQUAL;
39 aConstr1.aRightStr = "100";
40 aConstraints.push_back(aConstr1);
42 ModelConstraint aConstr2;
43 aConstr2.aLeftStr = "F5";
44 aConstr2.nOperator = CO_EQUAL;
45 aConstr2.aRightStr = "500";
46 aConstraints.push_back(aConstr2);
48 ModelConstraint aConstr3;
49 aConstr3.aLeftStr = "D1:D5";
50 aConstr3.nOperator = CO_BINARY;
51 aConstr3.aRightStr = "";
52 aConstraints.push_back(aConstr3);
54 return aConstraints;
57 // Tests the contents of the three constraints
58 void SolverTest::TestConstraintsModelA(SolverSettings* pSettings)
60 std::vector<ModelConstraint> aConstraints = pSettings->GetConstraints();
62 CPPUNIT_ASSERT_EQUAL(OUString("C1:C10"), aConstraints[0].aLeftStr);
63 CPPUNIT_ASSERT_EQUAL(CO_LESS_EQUAL, aConstraints[0].nOperator);
64 CPPUNIT_ASSERT_EQUAL(OUString("100"), aConstraints[0].aRightStr);
66 CPPUNIT_ASSERT_EQUAL(OUString("F5"), aConstraints[1].aLeftStr);
67 CPPUNIT_ASSERT_EQUAL(CO_EQUAL, aConstraints[1].nOperator);
68 CPPUNIT_ASSERT_EQUAL(OUString("500"), aConstraints[1].aRightStr);
70 CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), aConstraints[2].aLeftStr);
71 CPPUNIT_ASSERT_EQUAL(CO_BINARY, aConstraints[2].nOperator);
72 CPPUNIT_ASSERT_EQUAL(OUString(""), aConstraints[2].aRightStr);
75 /* This test creates a model in a single tab and test if the model info
76 * is correctly stored in the object
78 CPPUNIT_TEST_FIXTURE(SolverTest, testSingleModel)
80 createScDoc();
81 ScDocument* pDoc = getScDoc();
82 ScTable* pTable = pDoc->FetchTable(0);
83 std::shared_ptr<sc::SolverSettings> pSettings = pTable->GetSolverSettings();
84 CPPUNIT_ASSERT(pSettings);
86 // Test solver default settings on an empty tab
87 // Here we only test default settings that are not engine-dependent
88 CPPUNIT_ASSERT_EQUAL(OUString(""), pSettings->GetParameter(SP_OBJ_CELL));
89 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(OT_MAXIMIZE),
90 pSettings->GetParameter(SP_OBJ_TYPE).toInt32());
91 CPPUNIT_ASSERT_EQUAL(OUString(""), pSettings->GetParameter(SP_OBJ_VAL));
92 CPPUNIT_ASSERT_EQUAL(OUString(""), pSettings->GetParameter(SP_VAR_CELLS));
93 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
95 // Create a simple model
96 pSettings->SetParameter(SP_OBJ_CELL, OUString("A1"));
97 pSettings->SetParameter(SP_OBJ_TYPE, OUString::number(OT_MINIMIZE));
98 pSettings->SetParameter(SP_OBJ_VAL, OUString::number(0));
99 pSettings->SetParameter(SP_VAR_CELLS, OUString("D1:D5"));
100 std::vector<ModelConstraint> aConstraints = CreateConstraintsModelA();
101 pSettings->SetConstraints(aConstraints);
103 // Test if the model parameters were set
104 CPPUNIT_ASSERT_EQUAL(OUString("A1"), pSettings->GetParameter(SP_OBJ_CELL));
105 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(OT_MINIMIZE),
106 pSettings->GetParameter(SP_OBJ_TYPE).toInt32());
107 CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_OBJ_VAL));
108 CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), pSettings->GetParameter(SP_VAR_CELLS));
110 // Test if the constraints were correctly set before saving
111 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
112 TestConstraintsModelA(pSettings.get());
114 // Save and reload the file
115 pSettings->SaveSolverSettings();
116 saveAndReload("calc8");
117 pDoc = getScDoc();
118 pTable = pDoc->FetchTable(0);
119 pSettings = pTable->GetSolverSettings();
120 CPPUNIT_ASSERT(pSettings);
122 // Test if the model parameters remain set in the file
123 CPPUNIT_ASSERT_EQUAL(OUString("A1"), pSettings->GetParameter(SP_OBJ_CELL));
124 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(OT_MINIMIZE),
125 pSettings->GetParameter(SP_OBJ_TYPE).toInt32());
126 CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_OBJ_VAL));
127 CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), pSettings->GetParameter(SP_VAR_CELLS));
129 // Test if the constraints remain correct after saving
130 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
131 TestConstraintsModelA(pSettings.get());
134 // Tests if references remain valid after a sheet is renamed
135 CPPUNIT_TEST_FIXTURE(SolverTest, tdf156815)
137 createScDoc("ods/tdf156815.ods");
138 ScDocument* pDoc = getScDoc();
139 ScTable* pTable = pDoc->FetchTable(0);
140 std::shared_ptr<sc::SolverSettings> pSettings = pTable->GetSolverSettings();
141 CPPUNIT_ASSERT(pSettings);
143 // Check current values in the solver model
144 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$A$1"), pSettings->GetParameter(SP_OBJ_CELL));
145 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$A$3:$B$3"), pSettings->GetParameter(SP_VAR_CELLS));
147 std::vector<ModelConstraint> aConstraints = pSettings->GetConstraints();
148 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$A$2"), aConstraints[0].aLeftStr);
149 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$B$2"), aConstraints[0].aRightStr);
151 // Rename Sheet2 to NewName
152 ScDocFunc& rDocFunc = getScDocShell()->GetDocFunc();
153 rDocFunc.RenameTable(1, "NewName", false, true);
155 // Check whether the ranges where updated
156 pSettings = pTable->GetSolverSettings();
157 CPPUNIT_ASSERT(pSettings);
158 CPPUNIT_ASSERT_EQUAL(OUString("$NewName.$A$1"), pSettings->GetParameter(SP_OBJ_CELL));
159 CPPUNIT_ASSERT_EQUAL(OUString("$NewName.$A$3:$B$3"), pSettings->GetParameter(SP_VAR_CELLS));
161 aConstraints = pSettings->GetConstraints();
162 CPPUNIT_ASSERT_EQUAL(OUString("$NewName.$A$2"), aConstraints[0].aLeftStr);
163 CPPUNIT_ASSERT_EQUAL(OUString("$NewName.$B$2"), aConstraints[0].aRightStr);
166 // Tests if settings for the DEPS and SCO solvers are kept in the file
167 CPPUNIT_TEST_FIXTURE(SolverTest, tdf158735)
169 createScDoc("ods/tdf158735.ods");
170 ScDocument* pDoc = getScDoc();
172 // Test the non-default values of the DEPS model
173 ScTable* pTable = pDoc->FetchTable(0);
174 std::shared_ptr<sc::SolverSettings> pSettings = pTable->GetSolverSettings();
175 CPPUNIT_ASSERT(pSettings);
176 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl"),
177 pSettings->GetParameter(SP_LO_ENGINE));
178 CPPUNIT_ASSERT_EQUAL(OUString("0.45"), pSettings->GetParameter(SP_AGENT_SWITCH_RATE));
179 CPPUNIT_ASSERT_EQUAL(OUString("0.85"), pSettings->GetParameter(SP_CROSSOVER_PROB));
180 CPPUNIT_ASSERT_EQUAL(OUString("1500"), pSettings->GetParameter(SP_LEARNING_CYCLES));
181 CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_ENHANCED_STATUS));
183 // Test the non-default values of the SCO model
184 pTable = pDoc->FetchTable(1);
185 pSettings = pTable->GetSolverSettings();
186 CPPUNIT_ASSERT(pSettings);
187 CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl"),
188 pSettings->GetParameter(SP_LO_ENGINE));
189 CPPUNIT_ASSERT_EQUAL(OUString("180"), pSettings->GetParameter(SP_LIBRARY_SIZE));
190 CPPUNIT_ASSERT_EQUAL(OUString("0.00055"), pSettings->GetParameter(SP_STAGNATION_TOLERANCE));
191 CPPUNIT_ASSERT_EQUAL(OUString("1"), pSettings->GetParameter(SP_RND_STARTING_POINT));
192 CPPUNIT_ASSERT_EQUAL(OUString("80"), pSettings->GetParameter(SP_STAGNATION_LIMIT));
195 CPPUNIT_PLUGIN_IMPLEMENT();