/* * 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ package integration.forms;
/* ------------------------------------------------------------------ */
@Override public String getTestObjectName()
{ return"Database Form Controls Test";
}
/* ------------------------------------------------------------------ */ /// pre-test initialization publicvoid before() throws com.sun.star.uno.Exception, java.lang.Exception
{ // ensure that we have a data source to work with, and the required tables if ( !ensureDataSource() || !ensureTables() )
{
failed( "could not access the required data source or table therein." ); return;
}
// create the document which we work on
createSampleDocument();
// and check the content of the various controls if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkDoubleValue( 1, "ID", "Value" )
|| !checkDoubleValue( 42, "f_integer", "EffectiveValue" )
|| !checkStringValue( "the answer", "f_text", "Text" )
|| !checkDoubleValue( 0.12, "f_decimal", "Value" )
|| !checkIntValue ( 20030922, "f_date", "Date" )
|| !checkIntValue ( 15000000, "f_time", "Time" )
|| !checkIntValue ( 20030923, "f_timestamp_date", "Date" )
|| !checkIntValue ( 17152300, "f_timestamp_time", "Time" )
|| !checkShortValue ( (short)1, "f_tinyint", "State" )
)
{
failed( "checking the content of one or more controls on the first row failed (see the log for details)" ); return;
}
}
/* ------------------------------------------------------------------ */ publicvoid checkInsertRow() throws com.sun.star.uno.Exception, java.lang.Exception
{ // move the cursor to the insert row
moveToInsertRow();
// and check the content of the various controls if ( !verifyCleanInsertRow() )
{
failed( "checking the content of one or more controls on the insert row failed (see the log for details)" ); return;
}
}
/* ------------------------------------------------------------------ */ /// some tests with the image control publicvoid checkImageControl() throws com.sun.star.uno.Exception, java.lang.Exception
{ // since we did not yet insert any image, the control should not display one ...
moveToFirst(); if ( !verifyReferenceImage( newbyte[0] ) )
{
failed( "image control failed to display empty image" ); return;
}
// check if the image control is able to insert our sample image into the database // insert an
XPropertySet xImageModel = getControlModel( "f_blob" );
xImageModel.setPropertyValue( "ImageURL", m_sImageURL );
if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not display the sample image as required" ); return;
}
// save the record
saveRecordByUI();
// still needs to be the sample image if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not, after saving the record, display the sample image as required" ); return;
}
// on the next record, the image should be empty
moveToNext(); if ( !verifyReferenceImage( newbyte[0] ) )
{
failed( "image control failed to display empty image, after coming from a non-empty image" ); return;
}
// back to the record where we just inserted the image, it should be our sample image
moveToFirst(); if ( !verifyReferenceImage( getSamplePictureBytes() ) )
{
failed( "image control does not, after coming back to the record, display the sample image as required" ); return;
}
// okay, now remove the image
xImageModel.setPropertyValue( "ImageURL", "" ); if ( !verifyReferenceImage( newbyte[0] ) )
{
failed( "image control failed to remove the image" ); return;
}
nextRecordByUI();
previousRecordByUI(); if ( !verifyReferenceImage( newbyte[0] ) )
{
failed( "image still there after coming back, though we just removed it" ); return;
}
}
/* ------------------------------------------------------------------ */ /** This is both a test for controls which are bound to the same column (they must reflect * each others updates), and for the immediate updates which need to happen for both check * boxes and radio buttons: They must commit their content to the underlying column as soon * as the change is made, *not* only upon explicit commit
*/ publicvoid checkCrossUpdates_checkBox() throws com.sun.star.uno.Exception, java.lang.Exception
{ // move to the first record
moveToFirst(); if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
|| !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" )
)
{
failed( "huh? inconsistence in the test!" ); // we created the sample data in a way that the f_tinyint field should contain a "1" at the first // record. We already asserted the proper function of the check box in checkFirstRow, so if this // fails here, the script became inconsistent return;
}
// setting the state of the check box needs to be reflected in the formatted field immediately if ( !checkDoubleValue( 0, "f_tinyint_format", "EffectiveValue" ) )
{
failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (1)!" ); return;
}
// same for the "indetermined" state of the check box
checkModel.setPropertyValue( "State", Short.valueOf( (short)2 ) ); if ( !checkNullValue( "f_tinyint_format", "EffectiveValue" ) )
{
failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (2)!" ); return;
}
// undo the changes done so far
undoRecordByUI(); // and see if this is properly reflected in the controls if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
|| !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" )
)
{
failed( "either the check box or the formatted field failed to recognize the UNDO!" ); return;
}
// the other way round - when changing the formatted field - the change should *not* // be reflected to the check box, since the formatted field needs an explicit commit
XPropertySet tinyFormattedModel = getControlModel( "f_tinyint_format" );
m_document.getCurrentView().grabControlFocus( tinyFormattedModel );
m_formLayer.userTextInput( tinyFormattedModel, "0" ); if ( !checkShortValue ( (short)1, "f_tinyint", "State" )
)
{
failed( "the check box should not be updated here! (did the formatted model commit immediately?)" ); return;
}
// set the focus to *any* other control (since we just have it at hand, we use the check box control) // this should result in the formatted control being committed, and thus in the check box updating
m_document.getCurrentView().grabControlFocus( checkModel ); if ( !checkShortValue ( (short)0, "f_tinyint", "State" )
)
{
failed( "formatted field did not commit (or check box did not update)" ); return;
}
// undo the changes done so far, so we leave the document in a clean state for the next test
undoRecordByUI();
}
/* ------------------------------------------------------------------ */ /** very similar to checkCrossUpdates_checkBox - does nearly the same for the radio buttons. See there for more * explanations.
*/ publicvoid checkCrossUpdates_radioButton() throws com.sun.star.uno.Exception, java.lang.Exception
{ // move to the first record
moveToFirst(); if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkStringValue( "none", "f_text_enum_text", "Text" )
)
{
failed( "huh? inconsistence in the test!" ); return;
}
// setting the state of the radio button needs to be reflected in the formatted field immediately if ( !checkStringValue( "normal", "f_text_enum_text", "Text" ) )
{
failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (1)!" ); return;
}
// same for the "indetermined" state of the check box
getRadioModel( "radio_group", "important" ).setPropertyValue( "State", Short.valueOf( (short)1 ) ); if ( !checkStringValue( "important", "f_text_enum_text", "Text" ) )
{
failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (2)!" ); return;
}
// undo the changes done so far
undoRecordByUI(); // and see if this is properly reflected in the controls if ( !checkRadios( (short)1, (short)0, (short)0 )
|| !checkStringValue( "none", "f_text_enum_text", "Text" )
)
{
failed( "either the radio button or the text field failed to recognize the UNDO!"); return;
}
// the other way round - when changing the formatted field - the change should *not* // be reflected to the check box, since the formatted field needs an explicit commit
XPropertySet textModel = getControlModel( "f_text_enum_text" );
m_document.getCurrentView().grabControlFocus( textModel );
m_formLayer.userTextInput( textModel, "normal" ); if ( !checkRadios( (short)1, (short)0, (short)0 )
)
{
failed( "the radio buttons should not be updated here! (did the formatted model commit immediately?)" ); return;
}
// set the focus to *any* other control (since we just have it at hand, we use the check box control) // this should result in the formatted control being committed, and thus in the check box updating
m_document.getCurrentView().grabControlFocus( radioModel ); if ( !checkRadios( (short)0, (short)1, (short)0 )
)
{
failed( "text field did not commit (or radio button did not update)" ); return;
}
// undo the changes done so far, so we leave the document in a clean state for the next test
undoRecordByUI();
}
/* ------------------------------------------------------------------ */ /** some tests with updating the table via our controls
*/ publicvoid checkRowUpdates() throws com.sun.star.uno.Exception, java.lang.Exception
{ // start with inserting a new record
moveToInsertRow();
assure( "insert row not in expected clean state", verifyCleanInsertRow() );
// move to the next row, this should automatically commit the changes we made
nextRecordByUI(); // and back to the row we just inserted
previousRecordByUI();
if ( !checkDoubleValue( 3, "ID", "Value" )
|| !checkDoubleValue( 729, "f_integer", "EffectiveValue" )
|| !checkStringValue( "test", "f_text", "Text" )
|| !checkDoubleValue( 152343, "f_decimal", "Value" )
|| !checkIntValue ( 19991231, "f_date", "Date" )
|| !checkIntValue ( 23595900, "f_time", "Time" )
)
{
failed( "the changes we made on the insert row have not been committed" ); return;
}
// now change the data, to see if regular updates work, too
userTextInput( "ID", "4", true );
userTextInput( "f_integer", "618", true );
userTextInput( "f_text", "yet another stupid, meaningless text", true );
userTextInput( "f_required_text", "this must not be NULL", true );
userTextInput( "f_decimal", "4562", true );
userTextInput( "f_date", "26.03.2004", true );
userTextInput( "f_time", "17:05:00", true );
// move to the next row, this should automatically commit the changes we made
nextRecordByUI(); // and back to the row we just inserted
previousRecordByUI();
if ( !checkDoubleValue( 4, "ID", "Value" )
|| !checkDoubleValue( 618, "f_integer", "EffectiveValue" )
|| !checkStringValue( "yet another stupid, meaningless text", "f_text", "Text" )
|| !checkDoubleValue( 4562, "f_decimal", "Value" )
|| !checkIntValue ( 20040326, "f_date", "Date" )
|| !checkIntValue ( 17050000, "f_time", "Time" )
)
{
failed( "the changes we made on the insert row have not been committed" ); return;
}
/* ------------------------------------------------------------------ */ /** checks the "ConvertEmptyToNull" property behavior of an edit control *
*/ publicvoid checkEmptyIsNull() throws com.sun.star.uno.Exception, java.lang.Exception
{ // start with inserting a new record
moveToInsertRow();
assure( "insert row not in expected clean state", verifyCleanInsertRow() );
// make an input in any field, but leave the edit control which is bound to a required field // empty
userTextInput( "ID", "5", true );
userTextInput( "f_text", "more text", true );
// this should *not* fail. Even if we did not input anything into the control bound to the // f_required_text column, this control's reset (done when moving to the insertion row) is // expected to write an empty string into its bound column, since its EmptyIsNULL property // is set to FALSE // (#i92471#)
m_mostRecentErrorEvent = null;
nextRecordByUI();
assure( "updating an incomplete record did not work as expected", m_mostRecentErrorEvent == null );
}
// revoke the data source, if it previously existed if ( databaseContext.hasByName( m_dataSourceName ) )
namingService.revokeObject( m_dataSourceName );
// create a new ODB file, and register it with its URL
m_databaseDocument = new HsqlDatabase( m_orb );
String documentURL = m_databaseDocument.getDocumentURL();
namingService.registerObject( m_dataSourceName, databaseContext.getByName( documentURL ) );
/* ------------------------------------------------------------------ */ /** retrieves the control model with the given name
*/ private XPropertySet getControlModel( String name ) throws com.sun.star.uno.Exception, java.lang.Exception
{
XNameAccess nameAccess = UnoRuntime.queryInterface( XNameAccess.class,
m_masterForm ); return UnoRuntime.queryInterface( XPropertySet.class,
nameAccess.getByName( name ) );
}
// drop the table, if it already exists if ( !implExecuteStatement( "DROP TABLE \"" + s_tableName + "\" IF EXISTS" )
|| !implExecuteStatement( getCreateTableStatement() )
)
{
failed( "could not create the required sample table!" ); returnfalse;
}
String sInsertionPrefix = "INSERT INTO \"" + s_tableName + "\" VALUES (";
String[] aValues = getSampleDataValueString(); for ( int i=0; i<aValues.length; ++i ) if ( !implExecuteStatement( sInsertionPrefix + aValues[ i ] + ")" ) )
{
failed( "could not create the required sample data" ); returnfalse;
}
connection.refreshTables();
// do not need the connection anymore
connection.close();
returntrue;
}
/* ------------------------------------------------------------------ */ /// checks the 3 radio buttons for the given states privateboolean checkRadios( short stateNone, short stateNormal, short stateImportant ) throws com.sun.star.uno.Exception, java.lang.Exception
{ if ( ((Short)getRadioModel( "radio_group", "none" ).getPropertyValue( "State" )).shortValue() != stateNone )
{
failed( "wrong value of the 'none' radio button!" );
} elseif ( ((Short)getRadioModel( "radio_group", "normal" ).getPropertyValue( "State" )).shortValue() != stateNormal )
{
failed( "wrong value of the 'normal' radio button!" );
} elseif ( ((Short)getRadioModel( "radio_group", "important" ).getPropertyValue( "State")).shortValue() != stateImportant )
{
failed( "wrong value of the 'important' radio button!" );
} else returntrue;
returnfalse;
}
/* ------------------------------------------------------------------ */ privateboolean checkNullValue( String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{
Object value = getControlModel( fieldName ).getPropertyValue( propertyName ); if ( !util.utils.isVoid( value ) )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " );
log.println( " found : " + value.toString() );
} else returntrue;
returnfalse;
}
/* ------------------------------------------------------------------ */ privateboolean checkIntValue( int requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{ try
{ if ( "f_time".equals(fieldName) ) // http://bugs.mysql.com/bug.php?id=5681 returntrue; if (fieldName == null) { returnfalse;
} int currentValue = ((Integer)getControlModel( fieldName ).getPropertyValue( propertyName )).intValue(); if ( currentValue != requiredValue )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + requiredValue );
log.println( " found : " + currentValue );
} else returntrue;
} catch( com.sun.star.uno.Exception e )
{
log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" ); throw e;
}
returnfalse;
}
/* ------------------------------------------------------------------ */ privateboolean checkShortValue( short requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception
{ try
{ short currentValue = ((Short)getControlModel( fieldName ).getPropertyValue( propertyName )).shortValue(); if ( currentValue != requiredValue )
{
log.println( "wrong value of the " + fieldName + " field!" );
log.println( " expected: " + requiredValue );
log.println( " found : " + currentValue );
} else returntrue;
} catch( com.sun.star.uno.Exception e )
{
log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" ); throw e;
}
/* ------------------------------------------------------------------ */ /** executes the given statement on the given connection
*/ protectedboolean implExecuteStatement( String sStatement ) throws java.lang.Exception
{ try
{
m_databaseDocument.executeSQL( sStatement );
} catch(com.sun.star.sdbc.SQLException e)
{
System.err.println( e ); returnfalse;
}
returntrue;
}
/* ------------------------------------------------------------------ */ /** simulates a user's text input into a control given by model name
*/ privatevoid userTextInput( String modelName, String text, boolean withCommit ) throws com.sun.star.uno.Exception, java.lang.Exception
{
XPropertySet controlModel = getControlModel( modelName ); // the form runtime environment (namely the form controller) rely on focus events for recognizing // control content changes ... if ( withCommit )
m_document.getCurrentView().grabControlFocus( controlModel );
m_formLayer.userTextInput( controlModel, text );
// focus back to a dummy control model so the content of the model we just changed will // be committed to the underlying database column if ( withCommit )
m_document.getCurrentView().grabControlFocus( getControlModel( "dummy" ) );
}
PropertyValue[] aArgs = new PropertyValue[0];
xDispatch.dispatch( url[0], aArgs );
}
/* ------------------------------------------------------------------ */ /** undos the changes on the current record, by simulating pressing of the respective toolbox button
*/ privatevoid undoRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:RecUndo" );
}
/* ------------------------------------------------------------------ */ /** saves the current record, by simulating pressing of the respective toolbox button
*/ privatevoid saveRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:RecSave" );
}
/* ------------------------------------------------------------------ */ /** moves to the next record, by simulating pressing of the respective toolbox button
*/ privatevoid nextRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:NextRecord" );
} /* ------------------------------------------------------------------ */ /** moves to the previous record, by simulating pressing of the respective toolbox button
*/ privatevoid previousRecordByUI() throws java.lang.Exception
{
executeSlot( ".uno:PrevRecord" );
}
// check if the image control properly says that there currently is no image on the first record
XImageProducerSupplier xSuppProducer = UnoRuntime.queryInterface( XImageProducerSupplier.class,
xImageModel );
XImageProducer xProducer = xSuppProducer.getImageProducer();
ImageComparison compareImages = new ImageComparison( referenceBytes, this ); synchronized( this )
{
xProducer.addConsumer( compareImages );
xProducer.startProduction();
}
xProducer.removeConsumer( compareImages );
return compareImages.imagesEqual( );
}
/* ------------------------------------------------------------------ */ publicvoid errorOccured( SQLErrorEvent _event )
{ // just remember for the moment
m_mostRecentErrorEvent = _event;
}
/* ------------------------------------------------------------------ */ publicvoid disposing( EventObject _event )
{ // not interested in
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.