1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <sal/cppunit.h>
25 #include <rtl/ustrbuf.hxx>
26 
27 #include <com/sun/star/util/DateTime.hpp>
28 #include <com/sun/star/util/Date.hpp>
29 #include <com/sun/star/util/Duration.hpp>
30 
31 #include <sfx2/Metadatable.hxx>
32 #include <sfx2/XmlIdRegistry.hxx>
33 
34 
35 using namespace ::com::sun::star;
36 
37 
38 namespace {
39 
40 class MetadatableTest
41     : public ::CppUnit::TestFixture
42 {
43 public:
44     virtual void setUp();
45     virtual void tearDown();
46 
47     void test();
48 
49     CPPUNIT_TEST_SUITE(MetadatableTest);
50     CPPUNIT_TEST(test);
51     CPPUNIT_TEST_SUITE_END();
52 
53 private:
54 };
55 
setUp()56 void MetadatableTest::setUp()
57 {
58 }
59 
tearDown()60 void MetadatableTest::tearDown()
61 {
62 }
63 
64 
65 class MockMetadatable
66     : public ::sfx2::Metadatable
67 {
68 private:
69     ::sfx2::IXmlIdRegistry & m_rRegistry;
70 
71 public:
MockMetadatable(::sfx2::IXmlIdRegistry & i_rReg,bool const i_isInClip=false)72     MockMetadatable(::sfx2::IXmlIdRegistry & i_rReg,
73             bool const i_isInClip = false)
74         : m_rRegistry(i_rReg)
75         , m_bInClipboard(i_isInClip), m_bInUndo(false), m_bInContent(true) {}
76     bool m_bInClipboard;
77     bool m_bInUndo;
78     bool m_bInContent;
IsInClipboard() const79     virtual bool IsInClipboard() const { return m_bInClipboard; }
IsInUndo() const80     virtual bool IsInUndo() const { return m_bInUndo; }
IsInContent() const81     virtual bool IsInContent() const { return m_bInContent; }
GetRegistry()82     virtual ::sfx2::IXmlIdRegistry& GetRegistry() { return m_rRegistry; }
83     virtual ::com::sun::star::uno::Reference<
MakeUnoObject()84         ::com::sun::star::rdf::XMetadatable > MakeUnoObject() { return 0; }
85 };
86 
operator ==(beans::StringPair p1,beans::StringPair p2)87 static bool operator==(beans::StringPair p1, beans::StringPair p2)
88 {
89     return p1.First == p2.First && p1.Second == p2.Second;
90 }
91 
test()92 void MetadatableTest::test()
93 {
94     OSL_TRACE("SwMetadatable test(): start\n");
95     ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pReg(
96         ::sfx2::createXmlIdRegistry(false) );
97     ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pRegClip(
98         ::sfx2::createXmlIdRegistry(true) );
99 
100     MockMetadatable m1(*pReg);
101     MockMetadatable m2(*pReg);
102     MockMetadatable m3(*pReg);
103     MockMetadatable m4(*pReg);
104     MockMetadatable m5(*pReg);
105     ::rtl::OUString empty;
106     ::rtl::OUString content( ::rtl::OUString::createFromAscii("content.xml") );
107     ::rtl::OUString styles ( ::rtl::OUString::createFromAscii("styles.xml") );
108     ::rtl::OUString sid1( ::rtl::OUString::createFromAscii("id1") );
109     ::rtl::OUString sid2( ::rtl::OUString::createFromAscii("id2") );
110     ::rtl::OUString sid3( ::rtl::OUString::createFromAscii("id3") );
111     ::rtl::OUString sid4( ::rtl::OUString::createFromAscii("id4") );
112     beans::StringPair id1(content, sid1);
113     beans::StringPair id2(content, sid2);
114     beans::StringPair id3(content, sid3);
115     beans::StringPair id4(styles,  sid4);
116     beans::StringPair id3e(empty,  sid3);
117     beans::StringPair id4e(empty,  sid4);
118     m1.SetMetadataReference(id1);
119     CPPUNIT_ASSERT_MESSAGE("set failed", m1.GetMetadataReference() == id1);
120     try {
121         m2.SetMetadataReference(id1);
122         CPPUNIT_ASSERT_MESSAGE("set duplicate succeeded", false);
123     } catch (lang::IllegalArgumentException) { }
124     m1.SetMetadataReference(id1);
125     CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
126             m1.GetMetadataReference() == id1);
127     m1.EnsureMetadataReference();
128     CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
129             m1.GetMetadataReference() == id1);
130 
131     m2.EnsureMetadataReference();
132     beans::StringPair m2id(m2.GetMetadataReference());
133     CPPUNIT_ASSERT_MESSAGE("ensure failed", m2id.Second.getLength());
134     m2.EnsureMetadataReference();
135     CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
136             m2.GetMetadataReference() == m2id);
137 
138     m1.m_bInUndo = true;
139     CPPUNIT_ASSERT_MESSAGE("move to undo failed",
140             !m1.GetMetadataReference().Second.getLength());
141 
142     m1.m_bInUndo = false;
143     CPPUNIT_ASSERT_MESSAGE("move from undo failed",
144             m1.GetMetadataReference() == id1);
145 
146     m1.m_bInUndo = true;
147     try {
148         m2.SetMetadataReference(id1); // steal!
149     } catch (lang::IllegalArgumentException &) {
150         CPPUNIT_FAIL("set duplicate to undo failed");
151     }
152     m1.m_bInUndo = false;
153     CPPUNIT_ASSERT_MESSAGE("move from undo: duplicate",
154             !m1.GetMetadataReference().Second.getLength());
155 
156     m3.RegisterAsCopyOf(m2);
157     CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
158     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
159             !m3.GetMetadataReference().Second.getLength());
160     m4.RegisterAsCopyOf(m3);
161     CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
162     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
163             !m3.GetMetadataReference().Second.getLength());
164     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
165             !m4.GetMetadataReference().Second.getLength());
166     m2.m_bInUndo = true;
167     CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
168             m3.GetMetadataReference() == id1);
169     CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
170             !m2.GetMetadataReference().Second.getLength());
171     m2.m_bInUndo = false;
172     CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
173             m2.GetMetadataReference() == id1);
174     CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
175             !m3.GetMetadataReference().Second.getLength());
176 
177     m4.EnsureMetadataReference(); // new!
178     beans::StringPair m4id(m4.GetMetadataReference());
179     CPPUNIT_ASSERT_MESSAGE("ensure on duplicate",
180             m4id.Second.getLength() && !(m4id == id1));
181 
182     MockMetadatable mc1(*pRegClip, true); // in clipboard
183     MockMetadatable mc2(*pRegClip, true);
184     MockMetadatable mc3(*pRegClip, true);
185     MockMetadatable mc4(*pRegClip, true);
186     MockMetadatable m2p(*pReg);
187     MockMetadatable m3p(*pReg);
188 
189     mc1.SetMetadataReference(id2);
190     CPPUNIT_ASSERT_MESSAGE("set failed", mc1.GetMetadataReference() == id2);
191     try {
192         mc2.SetMetadataReference(id2);
193         CPPUNIT_FAIL("set duplicate succeeded");
194     } catch (lang::IllegalArgumentException) { }
195     mc1.SetMetadataReference(id2);
196     CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
197             mc1.GetMetadataReference() == id2);
198     mc1.EnsureMetadataReference();
199     CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
200             mc1.GetMetadataReference() == id2);
201     mc2.EnsureMetadataReference();
202     beans::StringPair mc2id(mc2.GetMetadataReference());
203     CPPUNIT_ASSERT_MESSAGE("ensure failed", mc2id.Second.getLength());
204     mc2.EnsureMetadataReference();
205     CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
206             mc2.GetMetadataReference() == mc2id);
207     mc2.RemoveMetadataReference();
208     CPPUNIT_ASSERT_MESSAGE("remove failed",
209             !mc2.GetMetadataReference().Second.getLength());
210 
211     // set up mc2 as copy of m2 and mc3 as copy of m3
212     mc3.RegisterAsCopyOf(m3);
213     CPPUNIT_ASSERT_MESSAGE("copy to clipboard (latent)",
214             !mc3.GetMetadataReference().Second.getLength() );
215     mc2.RegisterAsCopyOf(m2);
216     CPPUNIT_ASSERT_MESSAGE("copy to clipboard (non-latent)",
217             mc2.GetMetadataReference() == id1);
218     // paste mc2 to m2p and mc3 to m3p
219     m2p.RegisterAsCopyOf(mc2);
220     CPPUNIT_ASSERT_MESSAGE("paste from clipboard (non-latent)",
221             !m2p.GetMetadataReference().Second.getLength() );
222     m3p.RegisterAsCopyOf(mc3);
223     CPPUNIT_ASSERT_MESSAGE("paste from clipboard (latent)",
224             !m3p.GetMetadataReference().Second.getLength() );
225     // delete m2, m2p, m3
226     m2.RemoveMetadataReference();
227     CPPUNIT_ASSERT_MESSAGE("remove failed",
228             !m2.GetMetadataReference().Second.getLength());
229     CPPUNIT_ASSERT_MESSAGE("paste-remove (non-latent)",
230             m2p.GetMetadataReference() == id1);
231     m2p.RemoveMetadataReference();
232     CPPUNIT_ASSERT_MESSAGE("remove failed",
233             !m2p.GetMetadataReference().Second.getLength());
234     CPPUNIT_ASSERT_MESSAGE("paste-remove2 (non-latent)",
235             m3.GetMetadataReference() == id1);
236     m3.RemoveMetadataReference();
237     CPPUNIT_ASSERT_MESSAGE("remove failed",
238             !m3.GetMetadataReference().Second.getLength());
239     CPPUNIT_ASSERT_MESSAGE("paste-remove (latent)",
240             m3p.GetMetadataReference() == id1);
241     // delete mc2
242     mc2.SetMetadataReference(beans::StringPair());
243     CPPUNIT_ASSERT_MESSAGE("in clipboard becomes non-latent",
244             !mc3.GetMetadataReference().Second.getLength() );
245     // paste mc2
246     m2p.RegisterAsCopyOf(mc2);
247     CPPUNIT_ASSERT_MESSAGE("remove-paste",
248             !m2p.GetMetadataReference().Second.getLength());
249     CPPUNIT_ASSERT_MESSAGE("remove-paste (stolen)",
250             m3p.GetMetadataReference() == id1);
251 
252     // auto-detect stream
253     m5.SetMetadataReference(id3e);
254     CPPUNIT_ASSERT_MESSAGE("auto-detect (content)",
255             m5.GetMetadataReference() == id3);
256     m5.m_bInContent = false;
257     m5.SetMetadataReference(id4e);
258     CPPUNIT_ASSERT_MESSAGE("auto-detect (styles)",
259             m5.GetMetadataReference() == id4);
260 
261     OSL_TRACE("sfx2::Metadatable test(): finished\n");
262 }
263 
264 
265 CPPUNIT_TEST_SUITE_REGISTRATION(MetadatableTest);
266 
267 }
268 
269 CPPUNIT_PLUGIN_IMPLEMENT();
270 
271