bump product version to 5.0.4.1
[LibreOffice.git] / extensions / workben / pythonautotest.cxx
bloba7ee631e8a759f5b23b5b7b23a6c1e8b58bb0602
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #include <stardiv/uno/repos/implementationregistration.hxx>
22 #include <stardiv/uno/script/script.hxx>
23 #include <stardiv/uno/beans/exactname.hxx>
25 #include <rtl/ustring.hxx>
26 #include <osl/diagnose.h>
27 #include <usr/services.hxx>
28 #include <vcl/svapp.hxx>
29 #include <usr/ustring.hxx>
30 #include <usr/weak.hxx>
31 #include <osl/conditn.hxx>
33 using namespace usr;
35 using ::rtl::StringToOUString;
37 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
38 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
44 /*****
46 * A Test root object !
48 *****/
49 class MyPythonRoot :
50 public XInvokation,
51 public OWeakObject
53 public:
54 MyPythonRoot() { m_iTestValue = 15; }
55 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut );
56 void acquire() { OWeakObject::acquire(); }
57 void release() { OWeakObject::release(); }
58 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); }
60 public:
61 XIntrospectionAccessRef getIntrospection() const THROWS( (UsrSystemException) )
62 { return XIntrospectionAccessRef(); }
64 UsrAny invoke( const UString& FunctionName,
65 const Sequence< UsrAny >& Params,
66 Sequence< INT16 >& OutParamIndex,
67 Sequence< UsrAny >& OutParam)
68 THROWS( ( IllegalArgumentException,
69 CannotConvertException,
70 InvocationTargetException,
71 UsrSystemException) );
72 void setValue(const UString& PropertyName, const UsrAny& Value)
73 THROWS( ( UnknownPropertyException,
74 CannotConvertException,
75 InvocationTargetException,
76 UsrSystemException) );
78 UsrAny getValue(const UString& PropertyName)
79 THROWS( ( UnknownPropertyException,
80 UsrSystemException) );
81 BOOL hasMethod(const UString& Name) const THROWS( (UsrSystemException) );
82 BOOL hasProperty(const UString& Name) const THROWS( (UsrSystemException) );
85 void getTestValueViaInout( int &inout )
86 { inout = m_iTestValue; }
88 INT32 getTestValue() const
89 { return m_iTestValue; }
91 void setTestValue( INT32 i )
92 { m_iTestValue = i; }
94 void printTestValue()
95 { fprintf( stderr, "TestValue : %d\n" , getTestValue() ); }
97 void addTestValue( INT32 i )
98 { m_iTestValue += i; }
100 private:
102 INT32 m_iTestValue;
105 BOOL MyPythonRoot::queryInterface( Uik aUik, XInterfaceRef &rOut )
107 if( aUik == XInvokation::getSmartUik() ) {
108 rOut = ( XInvokation * ) this;
110 else {
111 return OWeakObject::queryInterface( aUik , rOut );
113 return TRUE;
117 UsrAny MyPythonRoot::invoke( const UString& FunctionName,
118 const Sequence< UsrAny >& Params,
119 Sequence< INT16 >& OutParamIndex,
120 Sequence< UsrAny >& OutParam)
121 THROWS( ( IllegalArgumentException,
122 CannotConvertException,
123 InvocationTargetException,
124 UsrSystemException) )
126 if( L"printTestValue" == FunctionName ) {
127 printTestValue();
129 else if( L"addTestValue" == FunctionName ) {
130 addTestValue( Params.getConstArray()[0].getINT32() );
132 else if( L"getTestValueViaInout" == FunctionName ) {
133 int i = Params.getConstArray()[0].getINT32();
134 getTestValueViaInout( i );
135 OutParam.getArray()[0].setINT32( i );
137 else {
138 THROW( InvocationTargetException() );
141 return UsrAny();
144 void MyPythonRoot::setValue(const UString& PropertyName, const UsrAny& Value)
145 THROWS( ( UnknownPropertyException,
146 CannotConvertException,
147 InvocationTargetException,
148 UsrSystemException) )
150 if( L"TestValue" == PropertyName ) {
151 setTestValue( Value.getINT32() );
153 else {
154 THROW( UnknownPropertyException() );
158 UsrAny MyPythonRoot::getValue(const UString& PropertyName)
159 THROWS( ( UnknownPropertyException,
160 UsrSystemException) )
162 UsrAny aRet;
164 if( L"TestValue" == PropertyName ) {
165 aRet.setINT32( getTestValue() );
167 else {
168 THROW( UnknownPropertyException() );
171 return aRet;
175 BOOL MyPythonRoot::hasMethod(const UString& Name) const THROWS( (UsrSystemException) )
177 if( L"printTestValue" == Name ) {
178 return TRUE;
180 else if( L"addTestValue" == Name ) {
181 return TRUE;
183 else if( L"getTestValueViaInout" == Name ) {
184 return TRUE;
186 return FALSE;
190 BOOL MyPythonRoot::hasProperty(const UString& Name) const THROWS( (UsrSystemException) )
192 if( L"TestValue" == Name ) {
193 return TRUE;
196 return FALSE;
200 /*****
202 * A test engine listener to check the debug interface
204 *****/
205 class TestListener :
206 public XEngineListener,
207 public OWeakObject
209 public:
211 TestListener()
213 m_pDebuggingRef = 0;
217 TestListener( XDebuggingRef *p )
219 attach( p );
222 ~TestListener()
224 if( m_pDebuggingRef ) {
225 detach();
229 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut );
230 void acquire() { OWeakObject::acquire(); }
231 void release() { OWeakObject::release(); }
232 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); }
235 void attach( XDebuggingRef *p )
237 m_pDebuggingRef = p;
240 void detach( );
243 virtual void disposing( const EventObject &o )
245 if( m_pDebuggingRef ) {
246 detach();
249 virtual void interrupt(const InterruptEngineEvent& Evt) THROWS( (UsrSystemException) )
253 virtual void running(const EventObject& Evt) THROWS( (UsrSystemException) )
255 (*m_pDebuggingRef)->stop();
257 m_aDebugCondition.set();
260 virtual void finished(const FinishEngineEvent& Evt) THROWS( (UsrSystemException) )
262 m_aDebugCondition.set();
266 void cmdLine();
267 protected:
269 osl::Condition m_aDebugCondition;
270 XDebuggingRef *m_pDebuggingRef;
275 void TestListener::cmdLine()
277 // Condition is set by running listener
278 m_aDebugCondition.wait();
279 m_aDebugCondition.reset();
280 (*m_pDebuggingRef)->doContinue();
281 m_aDebugCondition.wait();
284 void TestListener::detach()
286 OSL_ASSERT( m_pDebuggingRef );
288 m_pDebuggingRef = 0;
291 BOOL TestListener::queryInterface( Uik aUik, XInterfaceRef & rOut )
293 if( aUik == XEngineListener::getSmartUik() )
294 rOut = (XEngineListener*)this;
295 else
296 return OWeakObject::queryInterface( aUik, rOut );
297 return TRUE;
301 void checkInvokation( const XInvokationRef &xInvoke )
303 UsrAny anyList;
305 // check exporting an object as an invokation
306 OSL_ASSERT( xInvoke->hasProperty( L"list" ) );
307 anyList = xInvoke->getValue( L"list" );
309 OSL_ASSERT( anyList.getReflection() == XInvokation_getReflection() );
310 XInvokationRef *pRef = ( XInvokationRef * ) anyList.get();
311 OSL_ASSERT( (*pRef).is() );
313 OSL_ASSERT( (*pRef)->hasMethod( L"append" ) );
314 OSL_ASSERT( (*pRef)->hasMethod( L"count" ) );
316 Sequence<UsrAny> seq(1);
317 UsrAny any( (INT32) 1);
318 (seq.getArray())[0] = any;
320 any = (*pRef)->invoke( L"count" , seq , Sequence<INT16>(), Sequence<UsrAny>() );
321 int nOldSize = any.getINT32();
323 any = (*pRef)->invoke( L"append" , seq , Sequence<INT16>(), Sequence<UsrAny>() );
324 any = (*pRef)->invoke( L"count" , seq , Sequence<INT16>(), Sequence<UsrAny>() );
326 OSL_ASSERT( nOldSize + 1 == any.getINT32() );
329 // just for testing !
330 class PythonCodeLibrary :
331 public XLibraryAccess,
332 public OWeakObject
335 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut );
336 void acquire() { OWeakObject::acquire(); }
337 void release() { OWeakObject::release(); }
338 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); }
341 virtual BOOL isFunction(const UString& FunctionName) THROWS( (UsrSystemException) )
343 return FALSE;
346 virtual BOOL isValidPath(const UString& PathName) THROWS( (UsrSystemException) )
348 return FALSE;
351 virtual Sequence< UString > getModuleNames() THROWS( (UsrSystemException) )
353 return Sequence<UString> ();
356 virtual UString getModuleSource(const UString& ModulName) THROWS( (UsrSystemException) )
358 if( ModulName == L"testmodul" ) {
359 return UString( L"def testmethod():\n"
360 L" return 42\n");
362 return UString();
365 virtual Sequence< BYTE > getModuleCode(const UString& ModuleName) THROWS( (UsrSystemException) )
367 return Sequence< BYTE > ();
370 virtual UString getFunctionSource(const UString& FunctionName) THROWS( (UsrSystemException) )
372 return UString();
374 virtual Sequence< BYTE > getFunctionCode(const UString& FunctionName) THROWS( (UsrSystemException) )
376 return Sequence< BYTE > ();
380 BOOL PythonCodeLibrary::queryInterface( Uik aUik, XInterfaceRef & rOut )
382 if( XLibraryAccess::getSmartUik() == aUik ) {
383 rOut = (XLibraryAccess* ) this;
385 else {
386 return OWeakObject::queryInterface( aUik , rOut );
389 return TRUE;
395 * main.
397 int SAL_CALL main (int argc, char **argv)
399 // necessary startup code
400 XMultiServiceFactoryRef xSMgr = createRegistryServiceManager();
401 registerUsrServices( xSMgr );
402 setProcessServiceManager( xSMgr );
404 XInterfaceRef x = xSMgr->createInstance( L"stardiv.uno.repos.ImplementationRegistration" );
405 XImplementationRegistrationRef xReg( x, USR_QUERY );
406 sal_Char szBuf[1024];
408 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf, 1024 );
409 UString aDllName( StringToOUString( szBuf, CHARSET_SYSTEM ) );
410 xReg->registerImplementation( L"stardiv.loader.SharedLibrary", aDllName, XSimpleRegistryRef() );
412 x = xSMgr->createInstance( L"stardiv.script.Python" );
413 XEngineRef xEngine( x, USR_QUERY );
414 XInvokationRef xInvoke( x, USR_QUERY );
415 XDebuggingRef xDebug( x , USR_QUERY );
417 XInterfaceRef rRoot( (XInvokation * )new MyPythonRoot , USR_QUERY );
418 xEngine->setRoot( rRoot );
421 // execute a simple script
422 xEngine->run( L"nIntTest = 5\n"
423 L"list = [2,3,4]\n" , XInterfaceRef(), Sequence<UsrAny> () );
425 /****
427 * Xinvokation - Test
429 *****/
430 // get/set an int !
432 OSL_ASSERT( xInvoke->hasProperty( L"nIntTest" ) );
433 UsrAny any = xInvoke->getValue( L"nIntTest" );
435 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG );
436 OSL_ASSERT( any.getINT32() == 5 );
438 // simple test: set an int !
439 xInvoke->setValue( L"nIntTest" , UsrAny( (INT32) 10 ) );
440 any = xInvoke->getValue( L"nIntTest" );
442 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG );
443 OSL_ASSERT( any.getINT32() == 10 );
446 // call a python method !
448 xEngine->run( L"def foo():\n"
449 L" return 'this is foo'\n" , XInterfaceRef() , Sequence<UsrAny> () );
450 OSL_ASSERT( xInvoke->hasMethod( L"foo" ) );
451 UsrAny any = xInvoke->invoke( L"foo" ,
452 Sequence<UsrAny>(),
453 Sequence<INT16>() ,
454 Sequence<UsrAny> () );
455 OSL_ASSERT( any.getString() == L"this is foo" );
459 // check exception handling !
461 try {
462 xInvoke->invoke( L"foo" , Sequence<UsrAny>(1) , Sequence<INT16>(), Sequence<UsrAny> () );
463 // wrong number of arguments
464 OSL_ASSERT( 0 );
466 catch ( IllegalArgumentException& e ) {
468 catch ( InvocationTargetException& e ) {
470 catch ( CannotConvertException& e ) {
471 // empty any cannot be converted
475 // check InOut-Parameter
476 checkInvokation( xInvoke );
478 /*******
480 * Check Introspection Access
482 *******/
484 XIntrospectionAccessRef xIntrospection = xInvoke->getIntrospection();
485 OSL_ASSERT( xIntrospection.is() );
487 // no further test, simply call them
488 xIntrospection->getMethods(0);
489 xIntrospection->getProperties(0);
491 OSL_ASSERT( xIntrospection->getSuppliedMethodConcepts() == 0 );
492 OSL_ASSERT( xIntrospection->getSuppliedPropertyConcepts() == 0 );
494 Property prop = xIntrospection->getProperty( L"nIntTest" ,0 );
495 OSL_ASSERT( prop.Name == L"nIntTest" );
496 OSL_ASSERT( prop.Type->getTypeClass() == TypeClass_LONG );
498 XIdlMethodRef method = xIntrospection->getMethod( L"foo" , 0 );
499 OSL_ASSERT( method->getName() == L"foo" );
503 /******
505 * Multithreading test
507 *******/
509 /******
511 * XDebuggingTest
513 ******/
514 // stop/doContinue + runAsync listener
516 // test hangs, if something is wrong
518 TestListener *pListener = new TestListener( &xDebug );
519 XEngineListenerRef ref( (XEngineListener * ) pListener , USR_QUERY );
521 // single listener check !
522 xEngine->runAsync( L"pass\n"
523 , XInterfaceRef() , Sequence<UsrAny> () , ref );
524 pListener->cmdLine();
527 // ListenerAdministration check !
529 // test hangs, if something is wrong
531 TestListener *pListener = new TestListener( &xDebug );
532 XEngineListenerRef ref( (XEngineListener * ) pListener , USR_QUERY );
534 // engine listener check !
535 xEngine->addEngineListener( ref );
536 xEngine->runAsync( L"pass\n"
537 , XInterfaceRef() , Sequence<UsrAny> () , XEngineListenerRef() );
538 pListener->cmdLine();
539 xEngine->removeEngineListener( ref);
543 // check the import mechanism
545 XLibraryAccessRef xLibrary( ( XLibraryAccess * ) new PythonCodeLibrary , USR_QUERY );
546 xEngine->setLibraryAccess( xLibrary );
548 xEngine->run( L"import testmodul\n"
549 L"x = testmodul.testmethod()\n" , XInterfaceRef() , Sequence<UsrAny>() );
550 UsrAny any = xInvoke->getValue( L"x" );
551 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG );
552 OSL_ASSERT( any.getINT32() == 42 );
555 // check other imports
557 // Check, if the libraries are available at run time
558 xEngine->run( L"import math\n"
559 L"dMathTest = math.exp(0)\n" , XInterfaceRef() , Sequence<UsrAny> () );
561 OSL_ASSERT( xInvoke->hasProperty( L"dMathTest" ) );
562 UsrAny any = xInvoke->getValue( L"dMathTest" );
564 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_DOUBLE );
565 OSL_ASSERT( any.getDouble() == 1. );
568 // Test connection to root object !
570 xEngine->run( L"x = stardiv.root.TestValue\n"
571 L"y = stardiv.inout(5)\n"
572 L"stardiv.root.getTestValueViaInout(y)\n"
573 L"z = y.value\n" , XInterfaceRef() , Sequence<UsrAny> () );
575 UsrAny any = xInvoke->getValue( L"x" );
576 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG );
577 OSL_ASSERT( any.getINT32() == 15 );
579 any = xInvoke->getValue( L"z" );
580 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG );
581 OSL_ASSERT( any.getINT32() == 15 );
584 // Test exactName interface
586 UsrAny any = xInvoke->getValue( L"__builtins__" );
587 OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_INTERFACE );
589 XInvokationRef rInv( *((XInterfaceRef *) any.get() ), USR_QUERY );
590 OSL_ASSERT( rInv.is() );
592 XExactNameRef rName( *((XInterfaceRef*) any.get() ), USR_QUERY );
593 OSL_ASSERT( rName.is() );
595 UString str = rName->getExactName( L"SYNTAXERROR" );
596 OSL_ASSERT( str.len() );
600 // Test exactName interface of the engine itself
602 XExactNameRef rName( xInvoke , USR_QUERY );
603 OSL_ASSERT( rName.is() );
604 UString str = rName->getExactName( L"STARDIV" );
605 OSL_ASSERT( str.len() );
609 return 0;
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */