1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
10 #include <sal/config.h>
11 #include <test/unoapi_test.hxx>
12 #include <osl/file.hxx>
13 #include <sal/log.hxx>
14 
15 #include <vcl/svapp.hxx>
16 
17 #include <docsh.hxx>
18 #include <document.hxx>
19 
20 using namespace ::com::sun::star;
21 using namespace ::com::sun::star::uno;
22 
23 /* Implementation of Macros test */
24 
25 class ScMacrosTest : public UnoApiTest
26 {
27 public:
28     ScMacrosTest();
29 
30     void testStarBasic();
31     void testVba();
32     void testMSP();
33     void testPasswordProtectedStarBasic();
34     void testRowColumn();
35 
36     CPPUNIT_TEST_SUITE(ScMacrosTest);
37     CPPUNIT_TEST(testStarBasic);
38     CPPUNIT_TEST(testMSP);
39     CPPUNIT_TEST(testVba);
40     CPPUNIT_TEST(testPasswordProtectedStarBasic);
41     CPPUNIT_TEST(testRowColumn);
42 
43     CPPUNIT_TEST_SUITE_END();
44 };
45 
46 // I suppose you could say this test doesn't really belong here, OTOH
47 // we need a full document to run the test ( it related originally to an
48 // imported Excel VBA macro ) It's convenient and fast to unit test
49 // this the problem this way. Perhaps in the future there will be some sort
50 // of slowcheck tests ( requiring a full document environment in the scripting
51 // module, we could move the test there then ) - relates to fdo#67547
testMSP()52 void ScMacrosTest::testMSP()
53 {
54     const OUString aFileNameBase("MasterScriptProviderProblem.ods");
55     OUString aFileName;
56     createFileURL(aFileNameBase, aFileName);
57     uno::Reference< css::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument");
58 
59     CPPUNIT_ASSERT_MESSAGE("Failed to load MasterScriptProviderProblem.ods", xComponent.is());
60 
61     Any aRet;
62     Sequence< sal_Int16 > aOutParamIndex;
63     Sequence< Any > aOutParam;
64     Sequence< uno::Any > aParams;
65 
66     SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
67 
68     CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
69     ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
70     CPPUNIT_ASSERT(pDocSh != nullptr);
71 
72     SfxObjectShell::CallXScript(
73         xComponent,
74         "vnd.sun.Star.script:Standard.Module1.TestMSP?language=Basic&location=document",
75         aParams, aRet, aOutParamIndex, aOutParam);
76     OUString sResult;
77     aRet >>= sResult;
78 
79     SAL_INFO("sc.qa", "Result is " << sResult );
80     CPPUNIT_ASSERT_EQUAL_MESSAGE("TestMSP ( for fdo#67547) failed", OUString("OK"), sResult);
81     pDocSh->DoClose();
82 }
83 
testPasswordProtectedStarBasic()84 void ScMacrosTest::testPasswordProtectedStarBasic()
85 {
86     const OUString aFileNameBase("testTypePassword.ods");
87     OUString aFileName;
88     createFileURL(aFileNameBase, aFileName);
89     uno::Reference< css::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument");
90 
91     CPPUNIT_ASSERT_MESSAGE("Failed to load testTypePassword.ods", xComponent.is());
92 
93     Any aRet;
94     Sequence< sal_Int16 > aOutParamIndex;
95     Sequence< Any > aOutParam;
96     Sequence< uno::Any > aParams;
97 
98     SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
99 
100     CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
101     ScDocShell* pDocSh = static_cast<ScDocShell*>(pFoundShell);
102     ScDocument& rDoc = pDocSh->GetDocument();
103 
104 
105     // User defined types
106 
107     SfxObjectShell::CallXScript(
108         xComponent,
109         "vnd.sun.Star.script:MyLibrary.Module1.Main?language=Basic&location=document",
110         aParams, aRet, aOutParamIndex, aOutParam);
111 
112     OUString aValue = rDoc.GetString(0,0,0);
113     CPPUNIT_ASSERT_EQUAL_MESSAGE("User defined types script did not change the value of Sheet1.A1", OUString("success"), aValue);
114 
115     // Big Module
116 
117     SfxObjectShell::CallXScript(
118         xComponent,
119         "vnd.sun.Star.script:MyLibrary.BigModule.bigMethod?language=Basic&location=document",
120         aParams, aRet, aOutParamIndex, aOutParam);
121 
122     aValue = rDoc.GetString(1,0,0);
123     CPPUNIT_ASSERT_EQUAL_MESSAGE("Big module script did not change the value of Sheet1.B1", OUString("success"), aValue);
124 
125     // far big method tdf#94617
126 
127     SfxObjectShell::CallXScript(
128         xComponent,
129         "vnd.sun.Star.script:MyLibrary.BigModule.farBigMethod?language=Basic&location=document",
130         aParams, aRet, aOutParamIndex, aOutParam);
131 
132     aValue = rDoc.GetString(2,0,0);
133     CPPUNIT_ASSERT_EQUAL_MESSAGE("Far Method script did not change the value of Sheet1.C1", OUString("success"), aValue);
134 
135 
136     pDocSh->DoClose();
137 }
138 
testStarBasic()139 void ScMacrosTest::testStarBasic()
140 {
141     const OUString aFileNameBase("StarBasic.ods");
142     OUString aFileName;
143     createFileURL(aFileNameBase, aFileName);
144     uno::Reference< css::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument");
145 
146     CPPUNIT_ASSERT_MESSAGE("Failed to load StarBasic.ods", xComponent.is());
147 
148     Any aRet;
149     Sequence< sal_Int16 > aOutParamIndex;
150     Sequence< Any > aOutParam;
151     Sequence< uno::Any > aParams;
152 
153     SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
154 
155     CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
156     ScDocShell* pDocSh = static_cast<ScDocShell*>(pFoundShell);
157     ScDocument& rDoc = pDocSh->GetDocument();
158 
159     SfxObjectShell::CallXScript(
160         xComponent,
161         "vnd.sun.Star.script:Standard.Module1.Macro1?language=Basic&location=document",
162         aParams, aRet, aOutParamIndex, aOutParam);
163     double aValue;
164     rDoc.GetValue(0,0,0,aValue);
165     CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("script did not change the value of Sheet1.A1",2.0, aValue, 0.00001);
166     pDocSh->DoClose();
167 }
168 
testVba()169 void ScMacrosTest::testVba()
170 {
171     TestMacroInfo testInfo[] = {
172         {
173             OUString("TestAddress."),
174             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
175         },
176         {
177             OUString("vba."),
178             OUString("vnd.sun.Star.script:VBAProject.Modul1.Modul1?language=Basic&location=document"),
179         },
180         {
181             OUString("MiscRangeTests."),
182             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
183         },
184         {
185             OUString("bytearraystring."),
186             OUString("vnd.sun.Star.script:VBAProject.testMacro.test?language=Basic&location=document")
187         },
188         {
189             OUString("AutoFilter."),
190             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
191         },
192         {
193             OUString("CalcFont."),
194             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
195         },
196         {
197             OUString("TestIntersection."),
198             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
199         },
200         {
201             OUString("TestUnion."),
202             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
203         },
204         {
205             OUString("range-4."),
206             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
207         },
208         {
209             OUString("Ranges-3."),
210             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
211         },
212         {
213             OUString("TestCalc_Rangetest."),
214             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
215         },
216         {
217             OUString("TestCalc_Rangetest2."),
218             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
219         },
220         {
221             OUString("Ranges-2."),
222             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
223         },
224         {
225             OUString("pagesetup."),
226             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
227         },
228         {
229             OUString("Window."),
230             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
231         },
232         {
233             OUString("window2."),
234             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
235         },
236         {
237             OUString("PageBreaks."),
238             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
239         },
240         {
241             OUString("Shapes."),
242             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
243         },
244         {
245             OUString("Ranges."),
246             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
247         },
248         {
249             OUString("CheckOptionToggleValue."),
250             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
251         },
252         {
253             OUString("GeneratedEventTest."),
254             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
255         },
256         {
257             OUString("MiscControlTests."),
258             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
259         },
260         {
261             OUString("Workbooks."),
262             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
263         },
264         {
265             OUString("Names."),
266             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
267         },
268         {
269             OUString("vba_endFunction."),
270             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
271         },
272         {
273             OUString("vba_findFunction."),
274             OUString("vnd.sun.Star.script:VBAProject.testMacros.test?language=Basic&location=document")
275         },
276     };
277     OUString sTempDir;
278     OUString sTempDirURL;
279     osl::FileBase:: getTempDirURL( sTempDirURL );
280     osl::FileBase::getSystemPathFromFileURL( sTempDirURL, sTempDir );
281     sTempDir += OUStringChar(SAL_PATHDELIMITER);
282     OUString sTestFileName("My Test WorkBook.xls");
283     Sequence< uno::Any > aParams;
284     for ( size_t  i=0; i<SAL_N_ELEMENTS( testInfo ); ++i )
285     {
286         OUString aFileName;
287         createFileURL(testInfo[i].sFileBaseName + "xls", aFileName);
288         uno::Reference< css::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument");
289         OUString sMsg( "Failed to load " + aFileName );
290         CPPUNIT_ASSERT_MESSAGE( OUStringToOString( sMsg, RTL_TEXTENCODING_UTF8 ).getStr(), xComponent.is() );
291 
292         // process all events such as OnLoad events etc.
293         // otherwise the tend to arrive later at a random
294         // time - while processing other StarBasic methods.
295         Application::Reschedule(true);
296 
297         Any aRet;
298         Sequence< sal_Int16 > aOutParamIndex;
299         Sequence< Any > aOutParam;
300         bool bWorkbooksHandling = testInfo[i].sFileBaseName == "Workbooks." && !sTempDir.isEmpty() ;
301 
302         if ( bWorkbooksHandling )
303         {
304             aParams.realloc(2);
305             aParams[ 0 ] <<= sTempDir;
306             aParams[ 1 ] <<= sTestFileName;
307         }
308 
309         SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
310 
311         CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
312         SAL_INFO("sc.qa", "about to invoke vba test in " << aFileName << " with url " << testInfo[i].sMacroUrl);
313 
314         SfxObjectShell::CallXScript(
315             xComponent, testInfo[i].sMacroUrl, aParams, aRet, aOutParamIndex,
316             aOutParam);
317         OUString aStringRes;
318         aRet >>= aStringRes;
319         CPPUNIT_ASSERT_EQUAL_MESSAGE(
320             OUString("script reported failure in file " + testInfo[i].sFileBaseName + "xls")
321                 .toUtf8()
322                 .getStr(),
323             OUString("OK"), aStringRes);
324         pFoundShell->DoClose();
325         if ( bWorkbooksHandling )
326         {
327             OUString sFileUrl;
328             OUString sFilePath = sTempDir + sTestFileName;
329             osl::FileBase::getFileURLFromSystemPath( sFilePath, sFileUrl );
330             if ( !sFileUrl.isEmpty() )
331                 osl::File::remove( sFileUrl );
332         }
333     }
334 }
335 
testRowColumn()336 void ScMacrosTest::testRowColumn()
337 {
338     const OUString aFileNameBase("StarBasic.ods");
339     OUString aFileName;
340     createFileURL(aFileNameBase, aFileName);
341     uno::Reference< css::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument");
342 
343     CPPUNIT_ASSERT_MESSAGE("Failed to load StarBasic.ods", xComponent.is());
344 
345     Any aRet;
346     Sequence< sal_Int16 > aOutParamIndex;
347     Sequence< Any > aOutParam;
348     Sequence< uno::Any > aParams;
349 
350     SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
351 
352     CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
353     ScDocShell* pDocSh = static_cast<ScDocShell*>(pFoundShell);
354     ScDocument& rDoc = pDocSh->GetDocument();
355 
356     SfxObjectShell::CallXScript(
357         xComponent,
358         "vnd.sun.Star.script:Standard.Module1.Macro_RowHeight?language=Basic&location=document",
359         aParams, aRet, aOutParamIndex, aOutParam);
360 
361     sal_uInt16 nHeight = rDoc.GetRowHeight(0, 0) * HMM_PER_TWIPS;
362     CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(2000), nHeight);
363 
364     SfxObjectShell::CallXScript(
365         xComponent,
366         "vnd.sun.Star.script:Standard.Module1.Macro_ColumnWidth?language=Basic&location=document",
367         aParams, aRet, aOutParamIndex, aOutParam);
368     sal_uInt16 nWidth  = rDoc.GetColWidth(0, 0) * HMM_PER_TWIPS;
369     CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(4000), nWidth);
370 
371     pDocSh->DoClose();
372 }
373 
ScMacrosTest()374 ScMacrosTest::ScMacrosTest()
375       : UnoApiTest("/sc/qa/extras/testdocuments")
376 {
377 }
378 
379 CPPUNIT_TEST_SUITE_REGISTRATION(ScMacrosTest);
380 
381 CPPUNIT_PLUGIN_IMPLEMENT();
382 
383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
384