comparison truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java @ 22542:f8fb609939a7

Give implementors of the TCK control over comparing doubles.
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 06 Jan 2016 13:14:35 +0100
parents 89db2519ef18
children 0ef597d27256
comparison
equal deleted inserted replaced
22529:2643b968c0c6 22542:f8fb609939a7
24 */ 24 */
25 package com.oracle.truffle.tck; 25 package com.oracle.truffle.tck;
26 26
27 import com.oracle.truffle.tck.impl.LongBinaryOperation; 27 import com.oracle.truffle.tck.impl.LongBinaryOperation;
28 import com.oracle.truffle.tck.impl.ObjectBinaryOperation; 28 import com.oracle.truffle.tck.impl.ObjectBinaryOperation;
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertNotSame;
32 import static org.junit.Assert.assertNull;
33 import static org.junit.Assert.assertSame;
34 import static org.junit.Assert.assertTrue;
35 import static org.junit.Assert.fail;
36 29
37 import java.io.IOException; 30 import java.io.IOException;
38 import java.lang.reflect.Field; 31 import java.lang.reflect.Field;
39 import java.nio.ByteBuffer; 32 import java.nio.ByteBuffer;
40 import java.util.Arrays; 33 import java.util.Arrays;
52 import com.oracle.truffle.api.nodes.RootNode; 45 import com.oracle.truffle.api.nodes.RootNode;
53 import com.oracle.truffle.api.source.Source; 46 import com.oracle.truffle.api.source.Source;
54 import com.oracle.truffle.api.vm.PolyglotEngine; 47 import com.oracle.truffle.api.vm.PolyglotEngine;
55 import com.oracle.truffle.api.vm.PolyglotEngine.Language; 48 import com.oracle.truffle.api.vm.PolyglotEngine.Language;
56 import com.oracle.truffle.tck.Schema.Type; 49 import com.oracle.truffle.tck.Schema.Type;
50 import static org.junit.Assert.assertEquals;
51 import static org.junit.Assert.assertNotNull;
52 import static org.junit.Assert.assertNotSame;
53 import static org.junit.Assert.assertNull;
54 import static org.junit.Assert.assertSame;
55 import static org.junit.Assert.assertTrue;
56 import static org.junit.Assert.fail;
57 57
58 /** 58 /**
59 * Test compatibility kit (the <em>TCK</em>) is a collection of tests to certify your 59 * Test compatibility kit (the <em>TCK</em>) is a collection of tests to certify your
60 * {@link TruffleLanguage language implementation} compliance. If you want your language to be 60 * {@link TruffleLanguage language implementation} compliance. If you want your language to be
61 * compliant with most recent requirements of the Truffle infrastructure and tooling, subclass, 61 * compliant with most recent requirements of the Truffle infrastructure and tooling, subclass,
223 /** 223 /**
224 * Name of a function that adds up the real part of complex numbers. The function accepts one 224 * Name of a function that adds up the real part of complex numbers. The function accepts one
225 * argument and provides the sum of all real parts. The argument is an array/buffer of complex 225 * argument and provides the sum of all real parts. The argument is an array/buffer of complex
226 * numbers. 226 * numbers.
227 * 227 *
228 * @return name of globally exported symbol 228 * @return name of globally exported symbol, <code>null</code> if the test should be skipped
229 */ 229 */
230 protected String complexSumReal() { 230 protected String complexSumReal() {
231 throw new UnsupportedOperationException("complexSumReal() method not implemented"); 231 throw new UnsupportedOperationException("complexSumReal() method not implemented");
232 } 232 }
233 233
235 * Name of a function that copies a list of complex numbers. The function accepts two arguments 235 * Name of a function that copies a list of complex numbers. The function accepts two arguments
236 * and provides no return value. The arguments are two lists of complex numbers with members 236 * and provides no return value. The arguments are two lists of complex numbers with members
237 * called real and imaginary. The first argument is the destination, the second argument is the 237 * called real and imaginary. The first argument is the destination, the second argument is the
238 * source. 238 * source.
239 * 239 *
240 * @return name of globally exported symbol 240 * @return name of globally exported symbol, <code>null</code> if the test should be skipped
241 */ 241 */
242 protected String complexCopy() { 242 protected String complexCopy() {
243 throw new UnsupportedOperationException("complexCopy() method not implemented"); 243 throw new UnsupportedOperationException("complexCopy() method not implemented");
244 } 244 }
245 245
356 */ 356 */
357 protected String valuesObject() { 357 protected String valuesObject() {
358 throw new UnsupportedOperationException("valuesObject() method not implemented"); 358 throw new UnsupportedOperationException("valuesObject() method not implemented");
359 } 359 }
360 360
361 /** Assert two double values are the same. Various languages may have different
362 * semantics with respect to double numbers. Some of the language may not
363 * support <b>double</b> or <b>float</b> values at all. Those languages
364 * may override this method and compare the values with as much precision
365 * as they like.
366 * <p>
367 * Default implementation of this method calls
368 * {@link Assert#assertEquals(java.lang.String, double, double, double)}
369 * with delta <code>0.1</code>.
370 *
371 * @param msg assertion message to display in case of error
372 * @param expectedValue the value expected by the test
373 * @param actualValue the real value produced by the language
374 * @throws AssertionError if the values are different according to the language semantics
375 */
376 protected void assertDouble(String msg, double expectedValue, double actualValue) {
377 assertEquals(msg, expectedValue, actualValue, 0.1);
378 }
379
361 private PolyglotEngine vm() throws Exception { 380 private PolyglotEngine vm() throws Exception {
362 if (tckVM == null) { 381 if (tckVM == null) {
363 tckVM = prepareVM(); 382 tckVM = prepareVM();
364 } 383 }
365 return tckVM; 384 return tckVM;
464 assert a + b == n.longValue() : "The value is correct: (" + a + " + " + b + ") = " + n.longValue(); 483 assert a + b == n.longValue() : "The value is correct: (" + a + " + " + b + ") = " + n.longValue();
465 } 484 }
466 485
467 @Test 486 @Test
468 public void testPlusWithFloat() throws Exception { 487 public void testPlusWithFloat() throws Exception {
469 float a = RANDOM.nextFloat(); 488 float a = RANDOM.nextFloat() * 100.0f;
470 float b = RANDOM.nextFloat(); 489 float b = RANDOM.nextFloat() * 100.0f;
471 490
472 PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class)); 491 PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class));
473 492
474 Number n = plus.execute(a, b).as(Number.class); 493 Number n = plus.execute(a, b).as(Number.class);
475 assertEquals("Correct value computed", a + b, n.floatValue(), 0.01f); 494 assertDouble("Correct value computed", a + b, n.floatValue());
476 } 495 }
477 496
478 @Test 497 @Test
479 public void testPlusWithDouble() throws Exception { 498 public void testPlusWithDouble() throws Exception {
480 double a = RANDOM.nextDouble(); 499 double a = RANDOM.nextDouble() * 100.0;
481 double b = RANDOM.nextDouble(); 500 double b = RANDOM.nextDouble() * 100.0;
482 501
483 PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class)); 502 PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class));
484 503
485 Number n = plus.execute(a, b).as(Number.class); 504 Number n = plus.execute(a, b).as(Number.class);
486 assertEquals("Correct value computed", a + b, n.doubleValue(), 0.01); 505 assertDouble("Correct value computed", a + b, n.doubleValue());
487 } 506 }
488 507
489 @Test 508 @Test
490 public void testPlusWithIntsOnCompoundObject() throws Exception { 509 public void testPlusWithIntsOnCompoundObject() throws Exception {
491 int a = RANDOM.nextInt(100); 510 int a = RANDOM.nextInt(100);
590 609
591 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat(); 610 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
592 611
593 TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value)); 612 TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
594 Number n = apply.execute(fn).as(Number.class); 613 Number n = apply.execute(fn).as(Number.class);
595 assertEquals("The same value returned", value + 10, n.floatValue(), 0.01); 614 assertDouble("The same value returned", value + 10, n.floatValue());
596 } 615 }
597 616
598 @Test 617 @Test
599 public void testPrimitiveReturnTypeDouble() throws Exception { 618 public void testPrimitiveReturnTypeDouble() throws Exception {
600 PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers()); 619 PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
601 620
602 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble(); 621 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
603 622
604 TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value)); 623 TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
605 Number n = apply.execute(fn).as(Number.class); 624 Number n = apply.execute(fn).as(Number.class);
606 assertEquals("The same value returned", value + 10, n.doubleValue(), 0.01); 625 assertDouble("The same value returned", value + 10, n.doubleValue());
607 } 626 }
608 627
609 @Test 628 @Test
610 public void testPrimitiveidentityByte() throws Exception { 629 public void testPrimitiveidentityByte() throws Exception {
611 String id = identity(); 630 String id = identity();
730 PolyglotEngine.Value apply = findGlobalSymbol(id); 749 PolyglotEngine.Value apply = findGlobalSymbol(id);
731 750
732 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat(); 751 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
733 752
734 Number n = (Number) apply.execute(value).get(); 753 Number n = (Number) apply.execute(value).get();
735 assertEquals("The same value returned", value, n.floatValue(), 0.01); 754 assertDouble("The same value returned", value, n.floatValue());
736 } 755 }
737 756
738 @Test 757 @Test
739 public void testPrimitiveidentityBoxedFloat() throws Exception { 758 public void testPrimitiveidentityBoxedFloat() throws Exception {
740 String id = identity(); 759 String id = identity();
745 764
746 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat(); 765 float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
747 BoxedValue boxed = new BoxedValue(value); 766 BoxedValue boxed = new BoxedValue(value);
748 767
749 Number n = (Number) apply.execute(boxed).get(); 768 Number n = (Number) apply.execute(boxed).get();
750 assertEquals("The same value returned", value, n.floatValue(), 0.01); 769 assertDouble("The same value returned", value, n.floatValue());
751 } 770 }
752 771
753 @Test 772 @Test
754 public void testPrimitiveidentityDouble() throws Exception { 773 public void testPrimitiveidentityDouble() throws Exception {
755 String id = identity(); 774 String id = identity();
759 PolyglotEngine.Value apply = findGlobalSymbol(id); 778 PolyglotEngine.Value apply = findGlobalSymbol(id);
760 779
761 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble(); 780 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
762 781
763 Number n = (Number) apply.execute(value).get(); 782 Number n = (Number) apply.execute(value).get();
764 assertEquals("The same value returned", value, n.doubleValue(), 0.01); 783 assertDouble("The same value returned", value, n.doubleValue());
765 } 784 }
766 785
767 @Test 786 @Test
768 public void testPrimitiveidentityBoxedDouble() throws Exception { 787 public void testPrimitiveidentityBoxedDouble() throws Exception {
769 String id = identity(); 788 String id = identity();
774 793
775 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble(); 794 double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
776 BoxedValue boxed = new BoxedValue(value); 795 BoxedValue boxed = new BoxedValue(value);
777 796
778 Number n = (Number) apply.execute(boxed).get(); 797 Number n = (Number) apply.execute(boxed).get();
779 assertEquals("The same value returned", value, n.doubleValue(), 0.01); 798 assertDouble("The same value returned", value, n.doubleValue());
780 } 799 }
781 800
782 @Test 801 @Test
783 public void testPrimitiveidentityString() throws Exception { 802 public void testPrimitiveidentityString() throws Exception {
784 String id = identity(); 803 String id = identity();
878 897
879 double expect = Math.floor(RANDOM.nextDouble() * 100000.0) / 10.0; 898 double expect = Math.floor(RANDOM.nextDouble() * 100000.0) / 10.0;
880 Object parsed = function.execute("application/x-tck", "" + expect).get(); 899 Object parsed = function.execute("application/x-tck", "" + expect).get();
881 assertTrue("Expecting numeric result, was:" + expect, parsed instanceof Number); 900 assertTrue("Expecting numeric result, was:" + expect, parsed instanceof Number);
882 double value = ((Number) parsed).doubleValue(); 901 double value = ((Number) parsed).doubleValue();
883 assertEquals("Gets the double", expect, value, 0.01); 902 assertDouble("Gets the double", expect, value);
884 } 903 }
885 904
886 @Test 905 @Test
887 public void multiplyTwoVariables() throws Exception { 906 public void multiplyTwoVariables() throws Exception {
888 final String firstVar = "var" + (char) ('A' + RANDOM.nextInt(24)); 907 final String firstVar = "var" + (char) ('A' + RANDOM.nextInt(24));
922 PolyglotEngine.Value apply = findGlobalSymbol(id); 941 PolyglotEngine.Value apply = findGlobalSymbol(id);
923 942
924 ComplexNumbersRowBased numbers = new ComplexNumbersRowBased(new double[]{2, -1, 30, -1, 10, -1}); 943 ComplexNumbersRowBased numbers = new ComplexNumbersRowBased(new double[]{2, -1, 30, -1, 10, -1});
925 944
926 Number n = (Number) apply.execute(numbers).get(); 945 Number n = (Number) apply.execute(numbers).get();
927 assertEquals("The same value returned", 42.0, n.doubleValue(), 0.01); 946 assertDouble("The same value returned", 42.0, n.doubleValue());
928 } 947 }
929 948
930 @Test 949 @Test
931 public void testSumRealOfComplexNumbersB() throws Exception { 950 public void testSumRealOfComplexNumbersB() throws Exception {
932 String id = complexSumReal(); 951 String id = complexSumReal();
936 PolyglotEngine.Value apply = findGlobalSymbol(id); 955 PolyglotEngine.Value apply = findGlobalSymbol(id);
937 956
938 ComplexNumbersColumnBased numbers = new ComplexNumbersColumnBased(new double[]{2, 30, 10}, new double[]{-1, -1, -1}); 957 ComplexNumbersColumnBased numbers = new ComplexNumbersColumnBased(new double[]{2, 30, 10}, new double[]{-1, -1, -1});
939 958
940 Number n = (Number) apply.execute(numbers).get(); 959 Number n = (Number) apply.execute(numbers).get();
941 assertEquals("The same value returned", 42.0, n.doubleValue(), 0.01); 960 assertDouble("The same value returned", 42.0, n.doubleValue());
942 } 961 }
943 962
944 @Test 963 @Test
945 public void testSumRealOfComplexNumbersAsStructuredDataRowBased() throws Exception { 964 public void testSumRealOfComplexNumbersAsStructuredDataRowBased() throws Exception {
946 String id = complexSumReal(); 965 String id = complexSumReal();
953 byte[] buffer = new byte[(6 * Double.SIZE / Byte.SIZE)]; 972 byte[] buffer = new byte[(6 * Double.SIZE / Byte.SIZE)];
954 putDoubles(buffer, new double[]{2, -1, 30, -1, 10, -1}); 973 putDoubles(buffer, new double[]{2, -1, 30, -1, 10, -1});
955 StructuredData numbers = new StructuredData(buffer, schema); 974 StructuredData numbers = new StructuredData(buffer, schema);
956 975
957 Number n = (Number) apply.execute(numbers).get(); 976 Number n = (Number) apply.execute(numbers).get();
958 assertEquals("The same value returned", 42.0, n.doubleValue(), 0.01); 977 assertDouble("The same value returned", 42.0, n.doubleValue());
959 } 978 }
960 979
961 @Test 980 @Test
962 public void testSumRealOfComplexNumbersAsStructuredDataColumnBased() throws Exception { 981 public void testSumRealOfComplexNumbersAsStructuredDataColumnBased() throws Exception {
963 String id = complexSumReal(); 982 String id = complexSumReal();
971 putDoubles(buffer, new double[]{2, 30, 10, -1, -1, -1}); 990 putDoubles(buffer, new double[]{2, 30, 10, -1, -1, -1});
972 991
973 StructuredData numbers = new StructuredData(buffer, schema); 992 StructuredData numbers = new StructuredData(buffer, schema);
974 993
975 Number n = (Number) apply.execute(numbers).get(); 994 Number n = (Number) apply.execute(numbers).get();
976 assertEquals("The same value returned", 42.0, n.doubleValue(), 0.01); 995 assertDouble("The same value returned", 42.0, n.doubleValue());
977 } 996 }
978 997
979 @Test 998 @Test
980 public void testCopyComplexNumbersA() throws Exception { 999 public void testCopyComplexNumbersA() throws Exception {
981 String id = complexCopy(); 1000 String id = complexCopy();
1061 1080
1062 @Test 1081 @Test
1063 public void readWriteFloatValue() throws Exception { 1082 public void readWriteFloatValue() throws Exception {
1064 String id = valuesObject(); 1083 String id = valuesObject();
1065 ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class); 1084 ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
1066 assertEquals("Zero", 0, values.floatValue(), 0.1); 1085 assertDouble("Zero", 0, values.floatValue());
1067 final float value = RANDOM.nextFloat() * 1000.0f; 1086 final float value = RANDOM.nextFloat() * 1000.0f;
1068 values.floatValue(value); 1087 values.floatValue(value);
1069 assertEquals("Correct value", value, values.floatValue(), 0.1); 1088 assertDouble("Correct value", value, values.floatValue());
1070 } 1089 }
1071 1090
1072 @Test 1091 @Test
1073 public void readWriteDoubleValue() throws Exception { 1092 public void readWriteDoubleValue() throws Exception {
1074 String id = valuesObject(); 1093 String id = valuesObject();
1075 ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class); 1094 ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
1076 assertEquals("Zero", 0, values.doubleValue(), 0.1); 1095 assertDouble("Zero", 0, values.doubleValue());
1077 final double value = RANDOM.nextDouble() * 1000.0; 1096 final double value = RANDOM.nextDouble() * 1000.0;
1078 values.doubleValue(value); 1097 values.doubleValue(value);
1079 assertEquals("Correct value", value, values.doubleValue(), 0.1); 1098 assertDouble("Correct value", value, values.doubleValue());
1080 } 1099 }
1081 1100
1082 @Test 1101 @Test
1083 public void readWriteCharValue() throws Exception { 1102 public void readWriteCharValue() throws Exception {
1084 String id = valuesObject(); 1103 String id = valuesObject();