/*******************************************************************************
* Copyright (c) 2008, 2010 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
******************************************************************************/
package org.eclipse.rwt.internal.theme.css;
import java.io.*;
import junit.framework.TestCase;
import org.eclipse.rwt.Fixture;
import org.eclipse.rwt.apache.batik.css.parser.Parser;
import org.eclipse.rwt.internal.theme.*;
import org.eclipse.rwt.internal.theme.QxAnimation.Animation;
import org.w3c.css.sac.*;
public class PropertyResolver_Test extends TestCase {
private static Parser parser = new Parser();
private static ResourceLoader RESOURCE_LOADER
= ThemeTestUtil.createResourceLoader( Fixture.class );
public void testColor() throws Exception {
QxColor transparent
= PropertyResolver.readColor( parseProperty( "transparent" ) );
assertEquals( QxColor.TRANSPARENT, transparent );
QxColor white = PropertyResolver.readColor( parseProperty( "white" ) );
assertEquals( QxColor.WHITE, white );
QxColor black = PropertyResolver.readColor( parseProperty( "Black" ) );
assertEquals( QxColor.BLACK, black );
QxColor yellow = PropertyResolver.readColor( parseProperty( "yellow" ) );
assertEquals( QxColor.create( 255, 255, 0 ), yellow );
QxColor fb0 = PropertyResolver.readColor( parseProperty( "#fb0" ) );
QxColor ffbb00 = PropertyResolver.readColor( parseProperty( "#ffbb00" ) );
assertEquals( fb0, ffbb00 );
assertEquals( QxColor.create( 255, 187, 0 ), ffbb00 );
QxColor color1
= PropertyResolver.readColor( parseProperty( "rgb( 0, 127, 255 )" ) );
assertEquals( QxColor.create( 0, 127, 255 ), color1 );
QxColor color2
= PropertyResolver.readColor( parseProperty( "rgb( -10, 127, 300 )" ) );
assertEquals( color1, color2 );
QxColor colorP1
= PropertyResolver.readColor( parseProperty( "rgb( 0%, 50%, 100% )" ) );
assertEquals( color1, colorP1 );
QxColor colorP2
= PropertyResolver.readColor( parseProperty( "rgb( -10%, 50%, 110% )" ) );
assertEquals( colorP1, colorP2 );
QxColor inherit = PropertyResolver.readColor( parseProperty( "inherit" ) );
assertEquals( QxColor.TRANSPARENT, inherit );
try {
PropertyResolver.readColor( parseProperty( "rgb( 0%, 50, 100 )" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testDimension() throws Exception {
QxDimension zero = PropertyResolver.readDimension( parseProperty( "0px" ) );
assertNotNull( zero );
assertEquals( QxDimension.ZERO, zero );
QxDimension dim2 = PropertyResolver.readDimension( parseProperty( "2px" ) );
assertNotNull( dim2 );
assertEquals( QxDimension.create( 2 ), dim2 );
try {
PropertyResolver.readDimension( parseProperty( "2em" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testBoxdimensions() throws Exception {
LexicalUnit zeroUnit = parseProperty( "0px" );
QxBoxDimensions zero = PropertyResolver.readBoxDimensions( zeroUnit );
assertNotNull( zero );
assertEquals( QxBoxDimensions.ZERO, zero );
LexicalUnit unit1234 = parseProperty( "1px 2px 3px 4px" );
QxBoxDimensions bdim1234 = PropertyResolver.readBoxDimensions( unit1234 );
assertNotNull( bdim1234 );
assertEquals( QxBoxDimensions.create( 1, 2, 3, 4 ), bdim1234 );
LexicalUnit unit123 = parseProperty( "1px 2px 3px" );
QxBoxDimensions bdim123 = PropertyResolver.readBoxDimensions( unit123 );
assertNotNull( bdim123 );
assertEquals( QxBoxDimensions.create( 1, 2, 3, 2 ), bdim123 );
LexicalUnit unit12 = parseProperty( "1px 2px" );
QxBoxDimensions bdim12 = PropertyResolver.readBoxDimensions( unit12 );
assertNotNull( bdim12 );
assertEquals( QxBoxDimensions.create( 1, 2, 1, 2 ), bdim12 );
LexicalUnit illegalUnit1 = parseProperty( "2" );
try {
PropertyResolver.readBoxDimensions( illegalUnit1 );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
LexicalUnit illegalUnit2 = parseProperty( "2em" );
try {
PropertyResolver.readBoxDimensions( illegalUnit2 );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testBorderWidth() throws Exception {
int zero = PropertyResolver.readBorderWidth( parseProperty( "0px" ) );
assertEquals( 0, zero );
int width = PropertyResolver.readBorderWidth( parseProperty( "2px" ) );
assertEquals( 2, width );
int thin = PropertyResolver.readBorderWidth( parseProperty( "thin" ) );
assertEquals( PropertyResolver.THIN_VALUE, thin );
int medium = PropertyResolver.readBorderWidth( parseProperty( "medium" ) );
assertEquals( PropertyResolver.MEDIUM_VALUE, medium );
int thick = PropertyResolver.readBorderWidth( parseProperty( "thick" ) );
assertEquals( PropertyResolver.THICK_VALUE, thick );
int illegal = PropertyResolver.readBorderWidth( parseProperty( "1" ) );
assertEquals( -1, illegal );
int illegal2 = PropertyResolver.readBorderWidth( parseProperty( "fat" ) );
assertEquals( -1, illegal2 );
int negative = PropertyResolver.readBorderWidth( parseProperty( "-1px" ) );
assertEquals( -1, negative );
}
public void testBorderStyle() throws Exception {
String nonsense = PropertyResolver.readBorderStyle( parseProperty( "nonsense" ) );
assertNull( nonsense );
String none = PropertyResolver.readBorderStyle( parseProperty( "none" ) );
assertEquals( "none", none );
}
public void testBorder() throws Exception {
String input = "1";
try {
PropertyResolver.readBorder( parseProperty( input ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
input = "1px red blue green";
try {
PropertyResolver.readBorder( parseProperty( input ) );
fail();
} catch( Exception e ) {
// expected
}
input = "1px solid blue";
QxBorder border1 = PropertyResolver.readBorder( parseProperty( input ) );
assertEquals( QxBorder.create( 1, "solid", "#0000ff" ), border1 );
input = "1px solid rgb( 0, 0, 255 )";
QxBorder border2 = PropertyResolver.readBorder( parseProperty( input ) );
assertEquals( border1, border2 );
input = "rgb( 0, 0, 255 ) solid 1px";
QxBorder border3 = PropertyResolver.readBorder( parseProperty( input ) );
assertEquals( border1, border3 );
}
public void testFontStyle() throws Exception {
String normal = "normal";
assertEquals( normal,
PropertyResolver.readFontStyle( parseProperty( normal ) ) );
String italic = "italic";
assertEquals( italic,
PropertyResolver.readFontStyle( parseProperty( italic ) ) );
String oblique = "oblique";
assertNull( PropertyResolver.readFontStyle( parseProperty( oblique ) ) );
String inherit = "inherit";
assertNull( PropertyResolver.readFontStyle( parseProperty( inherit ) ) );
}
public void testFontWeight() throws Exception {
String normal = "normal";
assertEquals( normal,
PropertyResolver.readFontWeight( parseProperty( normal ) ) );
String bold = "bold";
assertEquals( bold,
PropertyResolver.readFontWeight( parseProperty( bold ) ) );
String bolder = "bolder";
assertNull( PropertyResolver.readFontWeight( parseProperty( bolder ) ) );
String inherit = "inherit";
assertNull( PropertyResolver.readFontWeight( parseProperty( inherit ) ) );
}
public void testFontSize() throws Exception {
assertEquals( 0, PropertyResolver.readFontSize( parseProperty( "0px" ) ) );
assertEquals( 2, PropertyResolver.readFontSize( parseProperty( "2px" ) ) );
assertEquals( -1, PropertyResolver.readFontSize( parseProperty( "2em" ) ) );
assertEquals( -1, PropertyResolver.readFontSize( parseProperty( "-1px" ) ) );
assertEquals( -1, PropertyResolver.readFontSize( parseProperty( "-2px" ) ) );
}
public void testFontFamily() throws Exception {
String input1 = "Helvetica";
String[] res1 = PropertyResolver.readFontFamily( parseProperty( input1 ) );
assertNotNull( res1 );
assertEquals( 1, res1.length );
assertEquals( "Helvetica", res1[ 0 ] );
String input2 = "Helvetica, sans-serif";
String[] res2 = PropertyResolver.readFontFamily( parseProperty( input2 ) );
assertNotNull( res2 );
assertEquals( 2, res2.length );
assertEquals( "sans-serif", res2[ 1 ] );
String input3 = "\"New Century Schoolbook\", serif";
String[] res3 = PropertyResolver.readFontFamily( parseProperty( input3 ) );
assertNotNull( res3 );
assertEquals( 2, res3.length );
assertEquals( "New Century Schoolbook", res3[ 0 ] );
String input4 = "'New Century Schoolbook', Times, serif";
String[] res4 = PropertyResolver.readFontFamily( parseProperty( input4 ) );
assertNotNull( res4 );
assertEquals( 3, res4.length );
}
public void testFont() throws Exception {
// http://www.w3.org/TR/CSS21/fonts.html#font-shorthand
String input1 = "9px Helvetica";
QxFont exp1 = QxFont.create( new String[] { "Helvetica" }, 9, false, false );
QxFont res1 = PropertyResolver.readFont( parseProperty( input1 ) );
assertEquals( exp1, res1 );
String input2 = "bold 12px Helvetica";
QxFont exp2 = QxFont.create( new String[] { "Helvetica" }, 12, true, false );
QxFont res2 = PropertyResolver.readFont( parseProperty( input2 ) );
assertEquals( exp2, res2 );
String input3 = "bold italic 8px Helvetica, sans-serif";
String[] family3 = new String[] { "Helvetica", "sans-serif" };
QxFont exp3 = QxFont.create( family3, 8, true, true );
QxFont res3 = PropertyResolver.readFont( parseProperty( input3 ) );
assertEquals( exp3, res3 );
String input4 = "8px Courier New, sans-serif";
String[] family4 = new String[] { "Courier New", "sans-serif" };
QxFont exp4 = QxFont.create( family4, 8, false, false );
QxFont res4 = PropertyResolver.readFont( parseProperty( input4 ) );
assertEquals( exp4, res4 );
try {
PropertyResolver.readFont( parseProperty( "Helvetica" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
try {
PropertyResolver.readFont( parseProperty( "bold Helvetica" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
try {
PropertyResolver.readFont( parseProperty( "8px" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
try {
PropertyResolver.readFont( parseProperty( "Helvetica 8px" ) );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testBackgroundImage() throws Exception {
// background-image: none;
String input = "none";
QxImage res1 = PropertyResolver.readBackgroundImage( parseProperty( input ),
RESOURCE_LOADER );
assertEquals( QxImage.NONE, res1 );
// background-image: url( "path" );
input = "url( \"" + Fixture.IMAGE_50x100 + "\" )";
QxImage res2 = PropertyResolver.readBackgroundImage( parseProperty( input ),
RESOURCE_LOADER );
QxImage expected = QxImage.valueOf( Fixture.IMAGE_50x100,
RESOURCE_LOADER );
assertEquals( expected, res2 );
// background-image: url( path );
input = "url( " + Fixture.IMAGE_50x100 + " )";
QxImage res3 = PropertyResolver.readBackgroundImage( parseProperty( input ),
RESOURCE_LOADER );
assertEquals( expected, res3 );
// background-image: "path";
input = "\"" + Fixture.IMAGE_50x100 + "\"";
try {
PropertyResolver.readBackgroundImage( parseProperty( input ),
RESOURCE_LOADER );
fail();
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testGradient() throws Exception {
String input1 = "gradient( linear, left top, left bottom, "
+ "from( #0000FF ), "
+ "color-stop( 50%, #00FF00 ), "
+ "to( #0000FF ) )";
QxImage res1 = PropertyResolver.readBackgroundImage( parseProperty( input1 ),
RESOURCE_LOADER );
assertNotNull( res1 );
assertTrue( res1.none );
assertNull( res1.path );
assertNull( res1.loader );
assertNotNull( res1.gradientColors );
assertEquals( 3, res1.gradientColors.length );
assertEquals( "#0000ff", res1.gradientColors[ 0 ] );
assertEquals( "#00ff00", res1.gradientColors[ 1 ] );
assertEquals( "#0000ff", res1.gradientColors[ 2 ] );
assertNotNull( res1.gradientPercents );
assertEquals( 3, res1.gradientPercents.length );
assertEquals( 0f, res1.gradientPercents[ 0 ], 0 );
assertEquals( 50f, res1.gradientPercents[ 1 ], 0 );
assertEquals( 100f, res1.gradientPercents[ 2 ], 0 );
String input2 = "gradient( linear, left top, left bottom, "
+ "color-stop( 0%, #0000FF ), "
+ "color-stop( 50%, #00FF00 ), "
+ "color-stop( 100%, #0000FF ) )";
QxImage res2 = PropertyResolver.readBackgroundImage( parseProperty( input2 ),
RESOURCE_LOADER );
assertNotNull( res2 );
assertTrue( res2.none );
assertNull( res2.path );
assertNull( res2.loader );
assertNotNull( res2.gradientColors );
assertEquals( 3, res2.gradientColors.length );
assertEquals( "#0000ff", res2.gradientColors[ 0 ] );
assertEquals( "#00ff00", res2.gradientColors[ 1 ] );
assertEquals( "#0000ff", res2.gradientColors[ 2 ] );
assertNotNull( res2.gradientPercents );
assertEquals( 3, res2.gradientPercents.length );
assertEquals( 0f, res2.gradientPercents[ 0 ], 0 );
assertEquals( 50f, res2.gradientPercents[ 1 ], 0 );
assertEquals( 100f, res2.gradientPercents[ 2 ], 0 );
String input3 = "gradient( linear, left top, left bottom, "
+ "color-stop( 50%, #00FF00 ) )";
QxImage res3 = PropertyResolver.readBackgroundImage( parseProperty( input3 ),
RESOURCE_LOADER );
assertNotNull( res3 );
assertTrue( res3.none );
assertNull( res3.path );
assertNull( res3.loader );
assertNotNull( res3.gradientColors );
assertEquals( 3, res3.gradientColors.length );
assertEquals( "#00ff00", res3.gradientColors[ 0 ] );
assertEquals( "#00ff00", res3.gradientColors[ 1 ] );
assertEquals( "#00ff00", res3.gradientColors[ 2 ] );
assertNotNull( res3.gradientPercents );
assertEquals( 3, res3.gradientPercents.length );
assertEquals( 0f, res3.gradientPercents[ 0 ], 0 );
assertEquals( 50f, res3.gradientPercents[ 1 ], 0 );
assertEquals( 100f, res3.gradientPercents[ 2 ], 0 );
String input4 = "gradient( linear, left top, left bottom, "
+ "from( #0000FF ), "
+ "to( #00FF00 ) )";
QxImage res4 = PropertyResolver.readBackgroundImage( parseProperty( input4 ),
RESOURCE_LOADER );
assertNotNull( res4 );
assertTrue( res4.none );
assertNull( res4.path );
assertNull( res4.loader );
assertNotNull( res4.gradientColors );
assertEquals( 2, res4.gradientColors.length );
assertEquals( "#0000ff", res4.gradientColors[ 0 ] );
assertEquals( "#00ff00", res4.gradientColors[ 1 ] );
assertNotNull( res4.gradientPercents );
assertEquals( 2, res4.gradientPercents.length );
assertEquals( 0f, res4.gradientPercents[ 0 ], 0 );
assertEquals( 100f, res4.gradientPercents[ 1 ], 0 );
String input5 = "gradient( radial, left top, left bottom, "
+ "from( #0000FF ), "
+ "to( #00FF00 ) )";
try {
PropertyResolver.readBackgroundImage( parseProperty( input5 ),
RESOURCE_LOADER );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
String input6 = "gradient( linear, 10 10, left bottom, "
+ "from( #0000FF ), "
+ "to( #00FF00 ) )";
try {
PropertyResolver.readBackgroundImage( parseProperty( input6 ),
RESOURCE_LOADER );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
String input7 = "gradient( linear, left top, 10 10, "
+ "from( #0000FF ), "
+ "to( #00FF00 ) )";
try {
PropertyResolver.readBackgroundImage( parseProperty( input7 ),
RESOURCE_LOADER );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
String input8 = "gradient( linear, left top, left bottom )";
try {
PropertyResolver.readBackgroundImage( parseProperty( input8 ),
RESOURCE_LOADER );
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testFloat() throws Exception {
QxFloat zero = PropertyResolver.readFloat( parseProperty( "0" ) );
assertNotNull( zero );
assertEquals( 0.0, zero.value, 0.001 );
QxFloat one = PropertyResolver.readFloat( parseProperty( "1" ) );
assertNotNull( one );
assertEquals( 1.0, one.value, 0.001 );
QxFloat floatValue = PropertyResolver.readFloat( parseProperty( "0.62" ) );
assertNotNull( floatValue );
assertEquals( 0.62, floatValue.value, 0.001 );
assertEquals( floatValue.toDefaultString(), "0.62" );
floatValue = null;
try {
floatValue = PropertyResolver.readFloat( parseProperty( "asdf" ) );
} catch( IllegalArgumentException e ) {
// expected
}
assertNull( floatValue );
try {
floatValue = PropertyResolver.readFloat( parseProperty( "-0.4" ) );
} catch( IllegalArgumentException e ) {
// expected
}
assertNull( floatValue );
try {
floatValue = PropertyResolver.readFloat( parseProperty( "1.0001" ) );
} catch( IllegalArgumentException e ) {
// expected
}
assertNull( floatValue );
}
public void testCursor() throws Exception {
// Test predefined cursor
String input = "default";
QxCursor res1 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res1 );
assertEquals( input, res1.value );
input = "pointer";
res1 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res1 );
assertEquals( input, res1.value );
input = "wait";
res1 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res1 );
assertEquals( input, res1.value );
input = "crosshair";
res1 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res1 );
assertEquals( input, res1.value );
// Test custom cursor
QxCursor expected = QxCursor.valueOf( Fixture.IMAGE_50x100,
RESOURCE_LOADER );
// cursor: url( "path" );
input = "url( \"" + Fixture.IMAGE_50x100 + "\" )";
QxCursor res2 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res2 );
assertEquals( expected, res2 );
// cursor: url( path );
input = "url( " + Fixture.IMAGE_50x100 + " )";
QxCursor res3 = PropertyResolver.readCursor( parseProperty( input ),
RESOURCE_LOADER );
assertNotNull( res3 );
assertEquals( expected, res3 );
}
public void testAnimation() throws Exception {
String input = "slideIn 2s ease-in";
QxAnimation result
= PropertyResolver.readAnimation( parseProperty( input ) );
assertNotNull( result );
assertEquals( 1, result.animations.length );
Animation animation = result.animations[ 0 ];
assertEquals( "slideIn", animation.name );
assertEquals( 2000, animation.duration );
assertEquals( "ease-in", animation.timingFunction );
input = "slideIn 2s ease-in, slideOut 200ms ease-out";
result = PropertyResolver.readAnimation( parseProperty( input ) );
assertNotNull( result );
assertEquals( 2, result.animations.length );
animation = result.animations[ 0 ];
assertEquals( "slideIn", animation.name );
assertEquals( 2000, animation.duration );
assertEquals( "ease-in", animation.timingFunction );
animation = result.animations[ 1 ];
assertEquals( "slideOut", animation.name );
assertEquals( 200, animation.duration );
assertEquals( "ease-out", animation.timingFunction );
input = "none";
result = PropertyResolver.readAnimation( parseProperty( input ) );
assertNotNull( result );
assertEquals( 0, result.animations.length );
input = "slideIn";
try {
result = PropertyResolver.readAnimation( parseProperty( input ) );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
input = "slideIn 2s";
try {
result = PropertyResolver.readAnimation( parseProperty( input ) );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
input = "slideIn abc ease-in";
try {
result = PropertyResolver.readAnimation( parseProperty( input ) );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
input = "slideIn 3s ease-in, slideOut";
try {
result = PropertyResolver.readAnimation( parseProperty( input ) );
fail( "Must throw IAE" );
} catch( IllegalArgumentException e ) {
// expected
}
}
public void testIsColorProperty() throws Exception {
assertFalse( PropertyResolver.isColorProperty( "border" ) );
assertTrue( PropertyResolver.isColorProperty( "color" ) );
assertTrue( PropertyResolver.isColorProperty( "background-color" ) );
assertTrue( PropertyResolver.isColorProperty( "background-gradient-color" ) );
assertTrue( PropertyResolver.isColorProperty( "rwt-selectionmarker-color" ) );
}
public void testIsBorderProperty() throws Exception {
assertTrue( PropertyResolver.isBorderProperty( "border" ) );
}
public void testIsFontProperty() throws Exception {
assertTrue( PropertyResolver.isFontProperty( "font" ) );
}
public void testIsBoxDimProperty() throws Exception {
assertTrue( PropertyResolver.isBoxDimensionProperty( "padding" ) );
assertTrue( PropertyResolver.isBoxDimensionProperty( "margin" ) );
}
public void testIsImageProperty() throws Exception {
assertTrue( PropertyResolver.isImageProperty( "background-image" ) );
}
public void testIsCursorProperty() throws Exception {
assertTrue( PropertyResolver.isCursorProperty( "cursor" ) );
}
public void testIsAnimationProperty() throws Exception {
assertTrue( PropertyResolver.isAnimationProperty( "animation" ) );
}
public void testResolveProperty() throws Exception {
LexicalUnit unit = parseProperty( "white" );
QxType value = PropertyResolver.resolveProperty( "color", unit, null );
assertEquals( QxColor.WHITE, value );
try {
PropertyResolver.resolveProperty( "xy", unit, null );
fail();
} catch( IllegalArgumentException e ) {
assertTrue( e.getMessage().indexOf( "property xy" ) != -1 );
}
try {
LexicalUnit unit2 = parseProperty( "darkslategray" );
PropertyResolver.resolveProperty( "color", unit2 , null );
fail();
} catch( IllegalArgumentException e ) {
assertTrue( e.getMessage().indexOf( "color darkslategray" ) != -1 );
}
}
private static LexicalUnit parseProperty( final String input )
throws CSSException, IOException
{
InputSource inputSource = new InputSource();
InputStream byteStream = new ByteArrayInputStream( input.getBytes() );
inputSource.setByteStream( byteStream );
return parser.parsePropertyValue( inputSource );
}
}