1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#include "basictest.hxx"
#include <osl/file.hxx>
#include <osl/process.h>

#include <basic/sbmod.hxx>
#include <basic/sbmeth.hxx>
#include <com/sun/star/awt/WindowDescriptor.hpp>
#include <com/sun/star/table/TableBorder.hpp>
#include <basic/sbuno.hxx>

namespace
{
    using namespace com::sun::star;
    class Nested_Struct : public test::BootstrapFixture
    {
        public:
        Nested_Struct(): BootstrapFixture(true, false) {};
        void testAssign1();
        void testAssign1Alt(); // result is uno-ised and tested
        void testOldAssign();
        void testOldAssignAlt(); // result is uno-ised and tested
        void testUnfixedVarAssign();
        void testUnfixedVarAssignAlt(); // result is uno-ised and tested
        void testFixedVarAssign();
        void testFixedVarAssignAlt(); // result is uno-ised and tested
        void testUnoAccess(); // fdo#60117 specific test

        // Adds code needed to register the test suite
        CPPUNIT_TEST_SUITE(Nested_Struct);

        // Declares the method as a test to call
        CPPUNIT_TEST(testAssign1);
        CPPUNIT_TEST(testAssign1Alt);
        CPPUNIT_TEST(testOldAssign);
        CPPUNIT_TEST(testOldAssignAlt);
        CPPUNIT_TEST(testUnfixedVarAssign);
        CPPUNIT_TEST(testUnfixedVarAssignAlt);
        CPPUNIT_TEST(testFixedVarAssign);
        CPPUNIT_TEST(testFixedVarAssignAlt);
        CPPUNIT_TEST(testUnoAccess);

        // End of test suite definition
        CPPUNIT_TEST_SUITE_END();
    };

// tests the new behaviour, we should be able to
// directly modify the value of the nested 'HorizontalLine' struct
OUString sTestSource1(
    "Function doUnitTest() as Integer\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\"\n"
    "b0.HorizontalLine.OuterLineWidth = 9\n"
    "doUnitTest = b0.HorizontalLine.OuterLineWidth\n"
    "End Function\n"
);

OUString sTestSource1Alt(
    "Function doUnitTest() as Object\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\"\n"
    "b0.HorizontalLine.OuterLineWidth = 9\n"
    "doUnitTest = b0\n"
    "End Function\n"
);

// tests the old behaviour, we should still be able
// to use the old workaround of
// a) creating a new instance BorderLine,
// b) cloning the new instance with the value of b0.HorizontalLine
// c) modifying the new instance
// d) setting b0.HorizontalLine with the value of the new instance
OUString sTestSource2(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\", l as new \"com.sun.star.table.BorderLine\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "doUnitTest = b0.HorizontalLine.OuterLineWidth\n"
"End Function\n"
);

OUString sTestSource2Alt(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\", l as new \"com.sun.star.table.BorderLine\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "doUnitTest = b0\n"
"End Function\n"
);
// it should be legal to assign a variant to a struct ( and copy by val )
// make sure we aren't copying by reference, we make sure that l is not
// a reference copy of b0.HorizontalLine, each one should have an
// OuterLineWidth of 4 & 9 respectively and we should be returning
// 13 the sum of the two ( hopefully unique values if we haven't copied by reference )
OUString sTestSource3(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "l.OuterLineWidth = 4\n"
    "doUnitTest = b0.HorizontalLine.OuterLineWidth + l.OuterLineWidth\n"
"End Function\n"
);

OUString sTestSource3Alt(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "l.OuterLineWidth = 4\n"
    "Dim result(1)\n"
    "result(0) = b0\n"
    "result(1) = l\n"
    "doUnitTest = result\n"
"End Function\n"
);

// nearly the same as above but this time for a fixed type
// variable
OUString sTestSource4(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\", l as new \"com.sun.star.table.BorderLine\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "l.OuterLineWidth = 4\n"
    "doUnitTest = b0.HorizontalLine.OuterLineWidth + l.OuterLineWidth\n"
"End Function\n"
);

OUString sTestSource4Alt(
    "Function doUnitTest()\n"
    "Dim b0 as new \"com.sun.star.table.TableBorder\", l as new \"com.sun.star.table.BorderLine\"\n"
    "l = b0.HorizontalLine\n"
    "l.OuterLineWidth = 9\n"
    "b0.HorizontalLine = l\n"
    "l.OuterLineWidth = 4\n"
    "Dim result(1)\n"
    "result(0) = b0\n"
    "result(1) = l\n"
    "doUnitTest = result\n"
"End Function\n"
);

// Although basic might appear to correctly change nested struct elements
// fdo#60117 shows that basic can be fooled ( and even the watch(ed) variable
// in the debugger shows the expected values )
// We need to additionally check the actual uno struct to see if the
// changes made are *really* reflected in the object
OUString sTestSource5(
    "Function doUnitTest() as Object\n"
    "Dim aWinDesc as new \"com.sun.star.awt.WindowDescriptor\"\n"
    "Dim aRect as new \"com.sun.star.awt.Rectangle\"\n"
    "aRect.X = 200\n"
    "aWinDesc.Bounds = aRect\n"
    "doUnitTest = aWinDesc\n"
"End Function\n"
);


void Nested_Struct::testAssign1()
{
    MacroSnippet myMacro( sTestSource1 );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testAssign1 fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(9), pNew->GetInteger());
}

void Nested_Struct::testAssign1Alt()
{
    MacroSnippet myMacro( sTestSource1Alt );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testAssign1Alt fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    uno::Any aRet = sbxToUnoValue( pNew.get() );<--- Variable 'aRet' is assigned a value that is never used.
    table::TableBorder aBorder;
    aRet >>= aBorder;<--- Variable 'aRet' is assigned a value that is never used.

    int result = aBorder.HorizontalLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL( 9, result );
}

void Nested_Struct::testOldAssign()
{
    MacroSnippet myMacro( sTestSource2 );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testOldAssign fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(9), pNew->GetInteger());
}

void Nested_Struct::testOldAssignAlt()
{
    MacroSnippet myMacro( sTestSource2Alt );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testOldAssign fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    uno::Any aRet = sbxToUnoValue( pNew.get() );<--- Variable 'aRet' is assigned a value that is never used.
    table::TableBorder aBorder;
    aRet >>= aBorder;<--- Variable 'aRet' is assigned a value that is never used.

    int result = aBorder.HorizontalLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL( 9, result );
}

void Nested_Struct::testUnfixedVarAssign()
{
    MacroSnippet myMacro( sTestSource3 );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testUnfixedVarAssign fails with compile error",!myMacro.HasError() );
    // forces a broadcast
    SbxVariableRef pNew = myMacro.Run();
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(13), pNew->GetInteger());
}

void Nested_Struct::testUnfixedVarAssignAlt()
{
    MacroSnippet myMacro( sTestSource3Alt );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testUnfixedVarAssignAlt fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    uno::Any aRet = sbxToUnoValue( pNew.get() );

    uno::Sequence< uno::Any > aResult;
    bool bRes = aRet >>= aResult;
    CPPUNIT_ASSERT_EQUAL(true, bRes );

    int result = aResult.getLength();
    // should have 2 elements in a sequence returned
    CPPUNIT_ASSERT_EQUAL(2, result );

    table::TableBorder aBorder;
    aResult[0] >>= aBorder;<--- Variable 'aResult[0]' is assigned a value that is never used.

    table::BorderLine aBorderLine;
    aResult[1] >>= aBorderLine;<--- Variable 'aResult[1]' is assigned a value that is never used.
    result = aBorder.HorizontalLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL(9, result );
    result = aBorderLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL(4, result );
}

void Nested_Struct::testFixedVarAssign()
{
    MacroSnippet myMacro( sTestSource4 );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testFixedVarAssign fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(13), pNew->GetInteger());
}

void Nested_Struct::testFixedVarAssignAlt()
{
    MacroSnippet myMacro( sTestSource4Alt );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testFixedVarAssignAlt fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    uno::Any aRet = sbxToUnoValue( pNew.get() );

    uno::Sequence< uno::Any > aResult;
    bool bRes = aRet >>= aResult;
    CPPUNIT_ASSERT_EQUAL(true, bRes );

    int result = aResult.getLength();
    // should have 2 elements in a sequence returned
    CPPUNIT_ASSERT_EQUAL(2, result );

    table::TableBorder aBorder;
    aResult[0] >>= aBorder;<--- Variable 'aResult[0]' is assigned a value that is never used.

    table::BorderLine aBorderLine;
    aResult[1] >>= aBorderLine;<--- Variable 'aResult[1]' is assigned a value that is never used.
    result = aBorder.HorizontalLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL(9, result );
    result = aBorderLine.OuterLineWidth;
    CPPUNIT_ASSERT_EQUAL(4, result );
}

void Nested_Struct::testUnoAccess()
{
    MacroSnippet myMacro( sTestSource5 );
    myMacro.Compile();
    CPPUNIT_ASSERT_MESSAGE("testUnoAccess fails with compile error",!myMacro.HasError() );
    SbxVariableRef pNew = myMacro.Run();
    uno::Any aRet = sbxToUnoValue( pNew.get() );<--- Variable 'aRet' is assigned a value that is never used.
    awt::WindowDescriptor aWinDesc;
    aRet >>= aWinDesc;<--- Variable 'aRet' is assigned a value that is never used.

    int result = aWinDesc.Bounds.X;
    CPPUNIT_ASSERT_EQUAL(200, result );
}

  // Put the test suite in the registry
  CPPUNIT_TEST_SUITE_REGISTRATION(Nested_Struct);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */