Mercurial > hg > truffle
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(); |