/* * 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 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pdfbox.pdmodel.common.function.type4; import org.junit.Assert; import junit.framework.TestCase; /** * Tests all implemented PostScript operators. * * @version $Revision$ */ public class TestOperators extends TestCase { /** * Tests the "add" operator. * @throws Exception if an error occurs */ public void testAdd() throws Exception { Type4Tester.create("5 6 add").pop(11).isEmpty(); Type4Tester.create("5 0.23 add").pop(5.23f).isEmpty(); int bigValue = Integer.MAX_VALUE - 2; ExecutionContext context = Type4Tester.create( bigValue + " " + bigValue + " add").toExecutionContext(); float floatResult = (Float)context.getStack().pop(); assertEquals(2 * (long)Integer.MAX_VALUE - 4, floatResult, 1); assertTrue(context.getStack().isEmpty()); } /** * Tests the "abs" operator. * @throws Exception if an error occurs */ public void testAbs() throws Exception { Type4Tester.create("-3 abs 2.1 abs -2.1 abs -7.5 abs") .pop(7.5f).pop(2.1f).pop(2.1f).pop(3).isEmpty(); } /** * Tests the "and" operator. * @throws Exception if an error occurs */ public void testAnd() throws Exception { Type4Tester.create("true true and true false and") .pop(false).pop(true).isEmpty(); Type4Tester.create("99 1 and 52 7 and") .pop(4).pop(1).isEmpty(); } /** * Tests the "atan" operator. * @throws Exception if an error occurs */ public void testAtan() throws Exception { Type4Tester.create("0 1 atan").pop(0f).isEmpty(); Type4Tester.create("1 0 atan").pop(90f).isEmpty(); Type4Tester.create("-100 0 atan").pop(270f).isEmpty(); Type4Tester.create("4 4 atan").pop(45f).isEmpty(); } /** * Tests the "ceiling" operator. * @throws Exception if an error occurs */ public void testCeiling() throws Exception { Type4Tester.create("3.2 ceiling -4.8 ceiling 99 ceiling") .pop(99).pop(-4f).pop(4f).isEmpty(); } /** * Tests the "cos" operator. * @throws Exception if an error occurs */ public void testCos() throws Exception { Type4Tester.create("0 cos").popReal(1f).isEmpty(); Type4Tester.create("90 cos").popReal(0f).isEmpty(); } /** * Tests the "cvi" operator. * @throws Exception if an error occurs */ public void testCvi() throws Exception { Type4Tester.create("-47.8 cvi").pop(-47).isEmpty(); Type4Tester.create("520.9 cvi").pop(520).isEmpty(); } /** * Tests the "cvr" operator. * @throws Exception if an error occurs */ public void testCvr() throws Exception { Type4Tester.create("-47.8 cvr").popReal(-47.8f).isEmpty(); Type4Tester.create("520.9 cvr").popReal(520.9f).isEmpty(); Type4Tester.create("77 cvr").popReal(77f).isEmpty(); //Check that the data types are really right ExecutionContext context = Type4Tester.create("77 77 cvr").toExecutionContext(); Assert.assertTrue("Expected a real as the result of 'cvr'", context.getStack().pop() instanceof Float); Assert.assertTrue("Expected an int from an integer literal", context.getStack().pop() instanceof Integer); } /** * Tests the "div" operator. * @throws Exception if an error occurs */ public void testDiv() throws Exception { Type4Tester.create("3 2 div").popReal(1.5f).isEmpty(); Type4Tester.create("4 2 div").popReal(2.0f).isEmpty(); } /** * Tests the "exp" operator. * @throws Exception if an error occurs */ public void testExp() throws Exception { Type4Tester.create("9 0.5 exp").popReal(3.0f).isEmpty(); Type4Tester.create("-9 -1 exp").popReal(-0.111111f, 0.000001).isEmpty(); } /** * Tests the "floor" operator. * @throws Exception if an error occurs */ public void testFloor() throws Exception { Type4Tester.create("3.2 floor -4.8 floor 99 floor") .pop(99).pop(-5f).pop(3f).isEmpty(); } /** * Tests the "div" operator. * @throws Exception if an error occurs */ public void testIDiv() throws Exception { Type4Tester.create("3 2 idiv").pop(1).isEmpty(); Type4Tester.create("4 2 idiv").pop(2).isEmpty(); Type4Tester.create("-5 2 idiv").pop(-2).isEmpty(); try { Type4Tester.create("4.4 2 idiv"); Assert.fail("Expected typecheck"); } catch (ClassCastException cce) { //expected } } /** * Tests the "ln" operator. * @throws Exception if an error occurs */ public void testLn() throws Exception { Type4Tester.create("10 ln").popReal(2.30259f, 0.00001f).isEmpty(); Type4Tester.create("100 ln").popReal(4.60517f, 0.00001f).isEmpty(); } /** * Tests the "log" operator. * @throws Exception if an error occurs */ public void testLog() throws Exception { Type4Tester.create("10 log").popReal(1.0f).isEmpty(); Type4Tester.create("100 log").popReal(2.0f).isEmpty(); } /** * Tests the "mod" operator. * @throws Exception if an error occurs */ public void testMod() throws Exception { Type4Tester.create("5 3 mod").pop(2).isEmpty(); Type4Tester.create("5 2 mod").pop(1).isEmpty(); Type4Tester.create("-5 3 mod").pop(-2).isEmpty(); try { Type4Tester.create("4.4 2 mod"); Assert.fail("Expected typecheck"); } catch (ClassCastException cce) { //expected } } /** * Tests the "mul" operator. * @throws Exception if an error occurs */ public void testMul() throws Exception { Type4Tester.create("1 2 mul").pop(2).isEmpty(); Type4Tester.create("1.5 2 mul").popReal(3.0f).isEmpty(); Type4Tester.create("1.5 2.1 mul").popReal(3.15f, 0.001).isEmpty(); Type4Tester.create((Integer.MAX_VALUE - 3) + " 2 mul") //integer overflow -> real .popReal(2L * (Integer.MAX_VALUE - 3), 0.001).isEmpty(); } /** * Tests the "neg" operator. * @throws Exception if an error occurs */ public void testNeg() throws Exception { Type4Tester.create("4.5 neg").popReal(-4.5f).isEmpty(); Type4Tester.create("-3 neg").pop(3).isEmpty(); //Border cases Type4Tester.create((Integer.MIN_VALUE + 1) + " neg") .pop(Integer.MAX_VALUE).isEmpty(); Type4Tester.create(Integer.MIN_VALUE + " neg") .popReal(-(float)Integer.MIN_VALUE).isEmpty(); } /** * Tests the "round" operator. * @throws Exception if an error occurs */ public void testRound() throws Exception { Type4Tester.create("3.2 round").popReal(3.0f).isEmpty(); Type4Tester.create("6.5 round").popReal(7.0f).isEmpty(); Type4Tester.create("-4.8 round").popReal(-5.0f).isEmpty(); Type4Tester.create("-6.5 round").popReal(-6.0f).isEmpty(); Type4Tester.create("99 round").pop(99).isEmpty(); } /** * Tests the "sin" operator. * @throws Exception if an error occurs */ public void testSin() throws Exception { Type4Tester.create("0 sin").popReal(0f).isEmpty(); Type4Tester.create("90 sin").popReal(1f).isEmpty(); Type4Tester.create("-90.0 sin").popReal(-1f).isEmpty(); } /** * Tests the "sqrt" operator. * @throws Exception if an error occurs */ public void testSqrt() throws Exception { Type4Tester.create("0 sqrt").popReal(0f).isEmpty(); Type4Tester.create("1 sqrt").popReal(1f).isEmpty(); Type4Tester.create("4 sqrt").popReal(2f).isEmpty(); Type4Tester.create("4.4 sqrt").popReal(2.097617f, 0.000001).isEmpty(); try { Type4Tester.create("-4.1 sqrt"); Assert.fail("Expected rangecheck"); } catch (IllegalArgumentException iae) { //expected } } /** * Tests the "sub" operator. * @throws Exception if an error occurs */ public void testSub() throws Exception { Type4Tester.create("5 2 sub -7.5 1 sub").pop(-8.5f).pop(3).isEmpty(); } /** * Tests the "truncate" operator. * @throws Exception if an error occurs */ public void testTruncate() throws Exception { Type4Tester.create("3.2 truncate").popReal(3.0f).isEmpty(); Type4Tester.create("-4.8 truncate").popReal(-4.0f).isEmpty(); Type4Tester.create("99 truncate").pop(99).isEmpty(); } /** * Tests the "bitshift" operator. * @throws Exception if an error occurs */ public void testBitshift() throws Exception { Type4Tester.create("7 3 bitshift 142 -3 bitshift") .pop(17).pop(56).isEmpty(); } /** * Tests the "eq" operator. * @throws Exception if an error occurs */ public void testEq() throws Exception { Type4Tester.create("7 7 eq 7 6 eq 7 -7 eq true true eq false true eq 7.7 7.7 eq") .pop(true).pop(false).pop(true).pop(false).pop(false).pop(true).isEmpty(); } /** * Tests the "ge" operator. * @throws Exception if an error occurs */ public void testGe() throws Exception { Type4Tester.create("5 7 ge 7 5 ge 7 7 ge -1 2 ge") .pop(false).pop(true).pop(true).pop(false).isEmpty(); } /** * Tests the "gt" operator. * @throws Exception if an error occurs */ public void testGt() throws Exception { Type4Tester.create("5 7 gt 7 5 gt 7 7 gt -1 2 gt") .pop(false).pop(false).pop(true).pop(false).isEmpty(); } /** * Tests the "le" operator. * @throws Exception if an error occurs */ public void testLe() throws Exception { Type4Tester.create("5 7 le 7 5 le 7 7 le -1 2 le") .pop(true).pop(true).pop(false).pop(true).isEmpty(); } /** * Tests the "lt" operator. * @throws Exception if an error occurs */ public void testLt() throws Exception { Type4Tester.create("5 7 lt 7 5 lt 7 7 lt -1 2 lt") .pop(true).pop(false).pop(false).pop(true).isEmpty(); } /** * Tests the "ne" operator. * @throws Exception if an error occurs */ public void testNe() throws Exception { Type4Tester.create("7 7 ne 7 6 ne 7 -7 ne true true ne false true ne 7.7 7.7 ne") .pop(false).pop(true).pop(false).pop(true).pop(true).pop(false).isEmpty(); } /** * Tests the "not" operator. * @throws Exception if an error occurs */ public void testNot() throws Exception { Type4Tester.create("true not false not") .pop(true).pop(false).isEmpty(); Type4Tester.create("52 not -37 not") .pop(37).pop(-52).isEmpty(); } /** * Tests the "or" operator. * @throws Exception if an error occurs */ public void testOr() throws Exception { Type4Tester.create("true true or true false or false false or") .pop(false).pop(true).pop(true).isEmpty(); Type4Tester.create("17 5 or 1 1 or") .pop(1).pop(21).isEmpty(); } /** * Tests the "cor" operator. * @throws Exception if an error occurs */ public void testXor() throws Exception { Type4Tester.create("true true xor true false xor false false xor") .pop(false).pop(true).pop(false).isEmpty(); Type4Tester.create("7 3 xor 12 3 or") .pop(15).pop(4); } /** * Tests the "if" operator. * @throws Exception if an error occurs */ public void testIf() throws Exception { Type4Tester.create("true { 2 1 add } if") .pop(3).isEmpty(); Type4Tester.create("false { 2 1 add } if") .isEmpty(); try { Type4Tester.create("0 { 2 1 add } if"); fail("Need typecheck error for the '0'"); } catch (ClassCastException cce) { //expected } } /** * Tests the "ifelse" operator. * @throws Exception if an error occurs */ public void testIfElse() throws Exception { Type4Tester.create("true { 2 1 add } { 2 1 sub } ifelse") .pop(3).isEmpty(); Type4Tester.create("false { 2 1 add } { 2 1 sub } ifelse") .pop(1).isEmpty(); } /** * Tests the "copy" operator. * @throws Exception if an error occurs */ public void testCopy() throws Exception { Type4Tester.create("true 1 2 3 3 copy") .pop(3).pop(2).pop(1) .pop(3).pop(2).pop(1) .pop(true) .isEmpty(); } /** * Tests the "dup" operator. * @throws Exception if an error occurs */ public void testDup() throws Exception { Type4Tester.create("true 1 2 dup") .pop(2).pop(2).pop(1) .pop(true) .isEmpty(); Type4Tester.create("true dup") .pop(true).pop(true).isEmpty(); } /** * Tests the "exch" operator. * @throws Exception if an error occurs */ public void testExch() throws Exception { Type4Tester.create("true 1 exch") .pop(true).pop(1).isEmpty(); Type4Tester.create("1 2.5 exch") .pop(1).pop(2.5f).isEmpty(); } /** * Tests the "index" operator. * @throws Exception if an error occurs */ public void testIndex() throws Exception { Type4Tester.create("1 2 3 4 0 index") .pop(4).pop(4).pop(3).pop(2).pop(1).isEmpty(); Type4Tester.create("1 2 3 4 3 index") .pop(1).pop(4).pop(3).pop(2).pop(1).isEmpty(); } /** * Tests the "pop" operator. * @throws Exception if an error occurs */ public void testPop() throws Exception { Type4Tester.create("1 pop 7 2 pop") .pop(7).isEmpty(); Type4Tester.create("1 2 3 pop pop") .pop(1).isEmpty(); } /** * Tests the "roll" operator. * @throws Exception if an error occurs */ public void testRoll() throws Exception { Type4Tester.create("1 2 3 4 5 5 -2 roll") .pop(2).pop(1).pop(5).pop(4).pop(3).isEmpty(); Type4Tester.create("1 2 3 4 5 5 2 roll") .pop(3).pop(2).pop(1).pop(5).pop(4).isEmpty(); Type4Tester.create("1 2 3 3 0 roll") .pop(3).pop(2).pop(1).isEmpty(); } }