|
16 | 16 |
|
17 | 17 | package io.objectbox.query;
|
18 | 18 |
|
19 |
| -import org.junit.Test; |
20 |
| - |
21 |
| -import java.util.Arrays; |
22 |
| -import java.util.List; |
23 |
| - |
24 | 19 | import io.objectbox.TestEntity;
|
25 | 20 | import io.objectbox.TestEntityCursor;
|
26 | 21 | import io.objectbox.exception.DbException;
|
27 | 22 | import io.objectbox.query.QueryBuilder.StringOrder;
|
| 23 | +import org.junit.Rule; |
| 24 | +import org.junit.Test; |
| 25 | +import org.junit.rules.ExpectedException; |
28 | 26 |
|
| 27 | +import java.util.Arrays; |
| 28 | +import java.util.List; |
29 | 29 |
|
30 |
| -import static io.objectbox.TestEntity_.simpleBoolean; |
31 |
| -import static io.objectbox.TestEntity_.simpleByte; |
32 |
| -import static io.objectbox.TestEntity_.simpleDouble; |
33 |
| -import static io.objectbox.TestEntity_.simpleFloat; |
34 |
| -import static io.objectbox.TestEntity_.simpleInt; |
35 |
| -import static io.objectbox.TestEntity_.simpleLong; |
36 |
| -import static io.objectbox.TestEntity_.simpleShort; |
37 |
| -import static io.objectbox.TestEntity_.simpleString; |
38 |
| -import static org.junit.Assert.assertEquals; |
39 |
| -import static org.junit.Assert.assertFalse; |
40 |
| -import static org.junit.Assert.assertNull; |
41 |
| -import static org.junit.Assert.assertTrue; |
| 30 | +import static io.objectbox.TestEntity_.*; |
| 31 | +import static org.junit.Assert.*; |
42 | 32 |
|
43 | 33 | public class PropertyQueryTest extends AbstractQueryTest {
|
44 | 34 |
|
| 35 | + @Rule |
| 36 | + public ExpectedException exceptionRule = ExpectedException.none(); |
| 37 | + |
| 38 | + private void putTestEntityInteger(byte vByte, short vShort, int vInt, long vLong) { |
| 39 | + TestEntity entity = new TestEntity(); |
| 40 | + entity.setSimpleByte(vByte); |
| 41 | + entity.setSimpleShort(vShort); |
| 42 | + entity.setSimpleInt(vInt); |
| 43 | + entity.setSimpleLong(vLong); |
| 44 | + box.put(entity); |
| 45 | + } |
| 46 | + |
| 47 | + private void putTestEntityFloat(float vFloat, double vDouble) { |
| 48 | + TestEntity entity = new TestEntity(); |
| 49 | + entity.setSimpleFloat(vFloat); |
| 50 | + entity.setSimpleDouble(vDouble); |
| 51 | + box.put(entity); |
| 52 | + } |
| 53 | + |
45 | 54 | @Test
|
46 | 55 | public void testFindStrings() {
|
47 | 56 | putTestEntity(null, 1000);
|
@@ -422,31 +431,300 @@ public void testFindShorts_wrongPropertyType() {
|
422 | 431 |
|
423 | 432 | @Test
|
424 | 433 | public void testCount() {
|
| 434 | + Query<TestEntity> query = box.query().build(); |
| 435 | + PropertyQuery stringQuery = query.property(simpleString); |
| 436 | + |
| 437 | + assertEquals(0, stringQuery.count()); |
| 438 | + |
425 | 439 | putTestEntity(null, 1000);
|
426 | 440 | putTestEntity("BAR", 100);
|
427 | 441 | putTestEntitiesStrings();
|
428 | 442 | putTestEntity("banana", 101);
|
429 |
| - Query<TestEntity> query = box.query().build(); |
430 |
| - PropertyQuery stringQuery = query.property(simpleString); |
| 443 | + |
431 | 444 | assertEquals(8, query.count());
|
432 | 445 | assertEquals(7, stringQuery.count());
|
433 | 446 | assertEquals(6, stringQuery.distinct().count());
|
434 | 447 | }
|
435 | 448 |
|
| 449 | + private void assertUnsupported(Runnable runnable, String exceptionMessage) { |
| 450 | + try { |
| 451 | + runnable.run(); |
| 452 | + fail("Should have thrown IllegalArgumentException: " + exceptionMessage); |
| 453 | + } catch (Exception e) { |
| 454 | + assertTrue( |
| 455 | + "Expected IllegalArgumentException, but was " + e.getClass().getSimpleName() + ".", |
| 456 | + e instanceof IllegalArgumentException |
| 457 | + ); |
| 458 | + assertTrue( |
| 459 | + "Expected exception message '" + exceptionMessage + "', but was '" + e.getMessage() + "'.", |
| 460 | + e.getMessage().contains(exceptionMessage) |
| 461 | + ); |
| 462 | + } |
| 463 | + } |
| 464 | + |
| 465 | + @Test |
| 466 | + public void avg_notSupported() { |
| 467 | + Query<TestEntity> query = box.query().build(); |
| 468 | + String exceptionMessage = "Property does not allow avg"; |
| 469 | + assertUnsupported(() -> query.property(simpleBoolean).avg(), exceptionMessage); |
| 470 | + assertUnsupported(() -> query.property(simpleByteArray).avg(), exceptionMessage); |
| 471 | + assertUnsupported(() -> query.property(simpleString).avg(), exceptionMessage); |
| 472 | + } |
| 473 | + |
| 474 | + @Test |
| 475 | + public void min_notSupported() { |
| 476 | + Query<TestEntity> query = box.query().build(); |
| 477 | + String exceptionMessage = "Property does not allow max"; // Note: currently JNI returns wrong error message. |
| 478 | + assertUnsupported(() -> query.property(simpleBoolean).min(), exceptionMessage); |
| 479 | + assertUnsupported(() -> query.property(simpleByteArray).min(), exceptionMessage); |
| 480 | + assertUnsupported(() -> query.property(simpleString).min(), exceptionMessage); |
| 481 | + |
| 482 | + assertUnsupported(() -> query.property(simpleFloat).min(), exceptionMessage); |
| 483 | + assertUnsupported(() -> query.property(simpleDouble).min(), exceptionMessage); |
| 484 | + } |
| 485 | + |
| 486 | + @Test |
| 487 | + public void minDouble_notSupported() { |
| 488 | + Query<TestEntity> query = box.query().build(); |
| 489 | + String exceptionMessage = "Property does not allow min (double)"; |
| 490 | + assertUnsupported(() -> query.property(simpleBoolean).minDouble(), exceptionMessage); |
| 491 | + assertUnsupported(() -> query.property(simpleByteArray).minDouble(), exceptionMessage); |
| 492 | + assertUnsupported(() -> query.property(simpleString).minDouble(), exceptionMessage); |
| 493 | + |
| 494 | + assertUnsupported(() -> query.property(simpleByte).minDouble(), exceptionMessage); |
| 495 | + assertUnsupported(() -> query.property(simpleShort).minDouble(), exceptionMessage); |
| 496 | + assertUnsupported(() -> query.property(simpleInt).minDouble(), exceptionMessage); |
| 497 | + assertUnsupported(() -> query.property(simpleLong).minDouble(), exceptionMessage); |
| 498 | + } |
| 499 | + |
| 500 | + @Test |
| 501 | + public void max_notSupported() { |
| 502 | + Query<TestEntity> query = box.query().build(); |
| 503 | + String exceptionMessage = "Property does not allow max"; |
| 504 | + assertUnsupported(() -> query.property(simpleBoolean).max(), exceptionMessage); |
| 505 | + assertUnsupported(() -> query.property(simpleByteArray).max(), exceptionMessage); |
| 506 | + assertUnsupported(() -> query.property(simpleString).max(), exceptionMessage); |
| 507 | + |
| 508 | + assertUnsupported(() -> query.property(simpleFloat).max(), exceptionMessage); |
| 509 | + assertUnsupported(() -> query.property(simpleDouble).max(), exceptionMessage); |
| 510 | + } |
| 511 | + |
| 512 | + @Test |
| 513 | + public void maxDouble_notSupported() { |
| 514 | + Query<TestEntity> query = box.query().build(); |
| 515 | + String exceptionMessage = "Property does not allow max (double)"; |
| 516 | + assertUnsupported(() -> query.property(simpleBoolean).maxDouble(), exceptionMessage); |
| 517 | + assertUnsupported(() -> query.property(simpleByteArray).maxDouble(), exceptionMessage); |
| 518 | + assertUnsupported(() -> query.property(simpleString).maxDouble(), exceptionMessage); |
| 519 | + |
| 520 | + assertUnsupported(() -> query.property(simpleByte).maxDouble(), exceptionMessage); |
| 521 | + assertUnsupported(() -> query.property(simpleShort).maxDouble(), exceptionMessage); |
| 522 | + assertUnsupported(() -> query.property(simpleInt).maxDouble(), exceptionMessage); |
| 523 | + assertUnsupported(() -> query.property(simpleLong).maxDouble(), exceptionMessage); |
| 524 | + } |
| 525 | + |
| 526 | + @Test |
| 527 | + public void sum_notSupported() { |
| 528 | + Query<TestEntity> query = box.query().build(); |
| 529 | + String exceptionMessage = "Property does not allow sum"; |
| 530 | + assertUnsupported(() -> query.property(simpleByteArray).sum(), exceptionMessage); |
| 531 | + assertUnsupported(() -> query.property(simpleString).sum(), exceptionMessage); |
| 532 | + |
| 533 | + String exceptionMessage2 = "Please use double based sum (e.g. `sumDouble()`) instead for property"; |
| 534 | + assertUnsupported(() -> query.property(simpleFloat).sum(), exceptionMessage2); |
| 535 | + assertUnsupported(() -> query.property(simpleDouble).sum(), exceptionMessage2); |
| 536 | + } |
| 537 | + |
| 538 | + @Test |
| 539 | + public void avg_noData() { |
| 540 | + Query<TestEntity> baseQuery = box.query().build(); |
| 541 | + // Integer. |
| 542 | + assertEquals(0, baseQuery.property(simpleByte).avg(), 0.0001); |
| 543 | + assertEquals(0, baseQuery.property(simpleShort).avg(), 0.0001); |
| 544 | + assertEquals(0, baseQuery.property(simpleInt).avg(), 0.0001); |
| 545 | + assertEquals(0, baseQuery.property(simpleLong).avg(), 0.0001); |
| 546 | + // Float. |
| 547 | + assertEquals(0, baseQuery.property(simpleFloat).avg(), 0.0001); |
| 548 | + assertEquals(0, baseQuery.property(simpleDouble).avg(), 0.0001); |
| 549 | + } |
| 550 | + |
| 551 | + @Test |
| 552 | + public void min_noData() { |
| 553 | + Query<TestEntity> baseQuery = box.query().build(); |
| 554 | + assertEquals(Long.MAX_VALUE, baseQuery.property(simpleByte).min()); |
| 555 | + assertEquals(Long.MAX_VALUE, baseQuery.property(simpleShort).min()); |
| 556 | + assertEquals(Long.MAX_VALUE, baseQuery.property(simpleInt).min()); |
| 557 | + assertEquals(Long.MAX_VALUE, baseQuery.property(simpleLong).min()); |
| 558 | + } |
| 559 | + |
| 560 | + @Test |
| 561 | + public void minDouble_noData() { |
| 562 | + Query<TestEntity> baseQuery = box.query().build(); |
| 563 | + assertEquals(Double.NaN, baseQuery.property(simpleFloat).minDouble(), 0.0001); |
| 564 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).minDouble(), 0.0001); |
| 565 | + } |
| 566 | + |
| 567 | + @Test |
| 568 | + public void max_noData() { |
| 569 | + Query<TestEntity> baseQuery = box.query().build(); |
| 570 | + assertEquals(Long.MIN_VALUE, baseQuery.property(simpleByte).max()); |
| 571 | + assertEquals(Long.MIN_VALUE, baseQuery.property(simpleShort).max()); |
| 572 | + assertEquals(Long.MIN_VALUE, baseQuery.property(simpleInt).max()); |
| 573 | + assertEquals(Long.MIN_VALUE, baseQuery.property(simpleLong).max()); |
| 574 | + } |
| 575 | + |
| 576 | + @Test |
| 577 | + public void maxDouble_noData() { |
| 578 | + Query<TestEntity> baseQuery = box.query().build(); |
| 579 | + assertEquals(Double.NaN, baseQuery.property(simpleFloat).maxDouble(), 0.0001); |
| 580 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).maxDouble(), 0.0001); |
| 581 | + } |
| 582 | + |
| 583 | + @Test |
| 584 | + public void sum_noData() { |
| 585 | + Query<TestEntity> baseQuery = box.query().build(); |
| 586 | + assertEquals(0, baseQuery.property(simpleByte).sum()); |
| 587 | + assertEquals(0, baseQuery.property(simpleShort).sum()); |
| 588 | + assertEquals(0, baseQuery.property(simpleInt).sum()); |
| 589 | + assertEquals(0, baseQuery.property(simpleLong).sum()); |
| 590 | + } |
| 591 | + |
| 592 | + @Test |
| 593 | + public void sumDouble_noData() { |
| 594 | + Query<TestEntity> baseQuery = box.query().build(); |
| 595 | + assertEquals(0, baseQuery.property(simpleFloat).sumDouble(), 0.0001); |
| 596 | + assertEquals(0, baseQuery.property(simpleDouble).sumDouble(), 0.0001); |
| 597 | + } |
| 598 | + |
| 599 | + @Test |
| 600 | + public void avg_positiveOverflow() { |
| 601 | + putTestEntityFloat(Float.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); |
| 602 | + putTestEntityFloat(1, 1); |
| 603 | + |
| 604 | + Query<TestEntity> baseQuery = box.query().build(); |
| 605 | + assertEquals(Float.NaN, baseQuery.property(simpleFloat).avg(), 0.001); |
| 606 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).avg(), 0.001); |
| 607 | + } |
| 608 | + |
| 609 | + @Test |
| 610 | + public void avg_negativeOverflow() { |
| 611 | + putTestEntityFloat(Float.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); |
| 612 | + putTestEntityFloat(-1, -1); |
| 613 | + |
| 614 | + Query<TestEntity> baseQuery = box.query().build(); |
| 615 | + assertEquals(Float.NaN, baseQuery.property(simpleFloat).avg(), 0.001); |
| 616 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).avg(), 0.001); |
| 617 | + } |
| 618 | + |
| 619 | + @Test |
| 620 | + public void avg_NaN() { |
| 621 | + putTestEntityFloat(Float.NaN, Double.NaN); |
| 622 | + putTestEntityFloat(1, 1); |
| 623 | + |
| 624 | + Query<TestEntity> baseQuery = box.query().build(); |
| 625 | + assertEquals(Float.NaN, baseQuery.property(simpleFloat).avg(), 0.001); |
| 626 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).avg(), 0.001); |
| 627 | + } |
| 628 | + |
| 629 | + @Test |
| 630 | + public void sum_byteShortIntOverflow() { |
| 631 | + putTestEntityInteger(Byte.MAX_VALUE, Short.MAX_VALUE, Integer.MAX_VALUE, 0); |
| 632 | + putTestEntityInteger((byte) 1, (short) 1, 1, 0); |
| 633 | + |
| 634 | + Query<TestEntity> baseQuery = box.query().build(); |
| 635 | + assertEquals(Byte.MAX_VALUE + 1, baseQuery.property(simpleByte).sum()); |
| 636 | + assertEquals(Short.MAX_VALUE + 1, baseQuery.property(simpleShort).sum()); |
| 637 | + assertEquals(Integer.MAX_VALUE + 1L, baseQuery.property(simpleInt).sum()); |
| 638 | + } |
| 639 | + |
| 640 | + @Test |
| 641 | + public void sum_longOverflow_exception() { |
| 642 | + exceptionRule.expect(DbException.class); |
| 643 | + exceptionRule.expectMessage("Numeric overflow"); |
| 644 | + |
| 645 | + putTestEntityInteger((byte) 0, (short) 0, 0, Long.MAX_VALUE); |
| 646 | + putTestEntityInteger((byte) 0, (short) 0, 0, 1); |
| 647 | + |
| 648 | + assertEquals(Long.MAX_VALUE, box.query().build().property(simpleLong).sum()); |
| 649 | + } |
| 650 | + |
| 651 | + @Test |
| 652 | + public void sumDouble_positiveOverflow_exception() { |
| 653 | + exceptionRule.expect(DbException.class); |
| 654 | + exceptionRule.expectMessage("Numeric overflow"); |
| 655 | + |
| 656 | + putTestEntityFloat(0, Double.POSITIVE_INFINITY); |
| 657 | + putTestEntityFloat(0, 1); |
| 658 | + |
| 659 | + box.query().build().property(simpleDouble).sumDouble(); |
| 660 | + } |
| 661 | + |
| 662 | + @Test |
| 663 | + public void sumDouble_negativeOverflow_exception() { |
| 664 | + exceptionRule.expect(DbException.class); |
| 665 | + exceptionRule.expectMessage("Numeric overflow (negative)"); |
| 666 | + |
| 667 | + putTestEntityFloat(0, Double.NEGATIVE_INFINITY); |
| 668 | + putTestEntityFloat(0, -1); |
| 669 | + |
| 670 | + box.query().build().property(simpleDouble).sumDouble(); |
| 671 | + } |
| 672 | + |
| 673 | + @Test |
| 674 | + public void sumDouble_NaN() { |
| 675 | + putTestEntityFloat(Float.NaN, Double.NaN); |
| 676 | + putTestEntityFloat(1, 1); |
| 677 | + |
| 678 | + Query<TestEntity> baseQuery = box.query().build(); |
| 679 | + assertEquals(Float.NaN, baseQuery.property(simpleFloat).sumDouble(), 0.001); |
| 680 | + assertEquals(Double.NaN, baseQuery.property(simpleDouble).sumDouble(), 0.001); |
| 681 | + } |
436 | 682 |
|
437 | 683 | @Test
|
438 | 684 | public void testAggregates() {
|
439 | 685 | putTestEntitiesScalars();
|
440 |
| - Query<TestEntity> query = box.query().less(simpleInt, 2002).build(); |
| 686 | + Query<TestEntity> query = box.query().less(simpleInt, 2002).build(); // 2 results. |
| 687 | + PropertyQuery booleanQuery = query.property(simpleBoolean); |
| 688 | + PropertyQuery byteQuery = query.property(simpleByte); |
| 689 | + PropertyQuery shortQuery = query.property(simpleShort); |
441 | 690 | PropertyQuery intQuery = query.property(simpleInt);
|
| 691 | + PropertyQuery longQuery = query.property(simpleLong); |
442 | 692 | PropertyQuery floatQuery = query.property(simpleFloat);
|
| 693 | + PropertyQuery doubleQuery = query.property(simpleDouble); |
| 694 | + // avg |
| 695 | + assertEquals(-37.5, byteQuery.avg(), 0.0001); |
| 696 | + assertEquals(2100.5, shortQuery.avg(), 0.0001); |
443 | 697 | assertEquals(2000.5, intQuery.avg(), 0.0001);
|
444 |
| - assertEquals(2000, intQuery.min(), 0.0001); |
| 698 | + assertEquals(3000.5, longQuery.avg(), 0.0001); |
| 699 | + assertEquals(400.05, floatQuery.avg(), 0.0001); |
| 700 | + assertEquals(2020.005, doubleQuery.avg(), 0.0001); |
| 701 | + // min |
| 702 | + assertEquals(-38, byteQuery.min()); |
| 703 | + assertEquals(2100, shortQuery.min()); |
| 704 | + assertEquals(2000, intQuery.min()); |
| 705 | + assertEquals(3000, longQuery.min()); |
445 | 706 | assertEquals(400, floatQuery.minDouble(), 0.001);
|
446 |
| - assertEquals(2001, intQuery.max(), 0.0001); |
| 707 | + assertEquals(2020, doubleQuery.minDouble(), 0.001); |
| 708 | + // max |
| 709 | + assertEquals(-37, byteQuery.max()); |
| 710 | + assertEquals(2101, shortQuery.max()); |
| 711 | + assertEquals(2001, intQuery.max()); |
| 712 | + assertEquals(3001, longQuery.max()); |
447 | 713 | assertEquals(400.1, floatQuery.maxDouble(), 0.001);
|
448 |
| - assertEquals(4001, intQuery.sum(), 0.0001); |
| 714 | + assertEquals(2020.01, doubleQuery.maxDouble(), 0.001); |
| 715 | + // sum |
| 716 | + assertEquals(1, booleanQuery.sum()); |
| 717 | + assertEquals(1, booleanQuery.sumDouble(), 0.001); |
| 718 | + assertEquals(-75, byteQuery.sum()); |
| 719 | + assertEquals(-75, byteQuery.sumDouble(), 0.001); |
| 720 | + assertEquals(4201, shortQuery.sum()); |
| 721 | + assertEquals(4201, shortQuery.sumDouble(), 0.001); |
| 722 | + assertEquals(4001, intQuery.sum()); |
| 723 | + assertEquals(4001, intQuery.sumDouble(), 0.001); |
| 724 | + assertEquals(6001, longQuery.sum()); |
| 725 | + assertEquals(6001, longQuery.sumDouble(), 0.001); |
449 | 726 | assertEquals(800.1, floatQuery.sumDouble(), 0.001);
|
| 727 | + assertEquals(4040.01, doubleQuery.sumDouble(), 0.001); |
450 | 728 | }
|
451 | 729 |
|
452 | 730 | @Test
|
|
0 commit comments