1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.arch.persistence.room.processor 18 19import COMMON 20import android.arch.persistence.room.parser.SQLTypeAffinity 21import android.arch.persistence.room.processor.ProcessorErrors.PRIMARY_KEY_NULL 22import android.arch.persistence.room.processor.ProcessorErrors.RELATION_IN_ENTITY 23import android.arch.persistence.room.vo.CallType 24import android.arch.persistence.room.vo.Field 25import android.arch.persistence.room.vo.FieldGetter 26import android.arch.persistence.room.vo.FieldSetter 27import android.arch.persistence.room.vo.Index 28import android.arch.persistence.room.vo.Pojo 29import com.google.testing.compile.JavaFileObjects 30import org.hamcrest.CoreMatchers.`is` 31import org.hamcrest.MatcherAssert.assertThat 32import org.junit.Test 33import org.junit.runner.RunWith 34import org.junit.runners.JUnit4 35import javax.lang.model.type.TypeKind.INT 36 37@RunWith(JUnit4::class) 38class EntityProcessorTest : BaseEntityParserTest() { 39 @Test 40 fun simple() { 41 singleEntity(""" 42 @PrimaryKey 43 private int id; 44 public int getId() { return id; } 45 public void setId(int id) { this.id = id; } 46 """) { entity, invocation -> 47 assertThat(entity.type.toString(), `is`("foo.bar.MyEntity")) 48 assertThat(entity.fields.size, `is`(1)) 49 val field = entity.fields.first() 50 val intType = invocation.processingEnv.typeUtils.getPrimitiveType(INT) 51 assertThat(field, `is`(Field( 52 element = field.element, 53 name = "id", 54 type = intType, 55 columnName = "id", 56 affinity = SQLTypeAffinity.INTEGER))) 57 assertThat(field.setter, `is`(FieldSetter("setId", intType, CallType.METHOD))) 58 assertThat(field.getter, `is`(FieldGetter("getId", intType, CallType.METHOD))) 59 assertThat(entity.primaryKey.fields, `is`(listOf(field))) 60 }.compilesWithoutError() 61 } 62 63 @Test 64 fun noGetter() { 65 singleEntity(""" 66 @PrimaryKey 67 private int id; 68 public void setId(int id) {this.id = id;} 69 """) { _, _ -> } 70 .failsToCompile() 71 .withErrorContaining(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD) 72 } 73 74 @Test 75 fun getterWithBadType() { 76 singleEntity(""" 77 @PrimaryKey 78 private int id; 79 public float getId() {return 0f;} 80 public void setId(int id) {this.id = id;} 81 """) { _, _ -> } 82 .failsToCompile() 83 .withErrorContaining(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD) 84 } 85 86 @Test 87 fun setterWithBadType() { 88 singleEntity(""" 89 @PrimaryKey 90 private int id; 91 public int getId() {return id;} 92 public void setId(float id) {} 93 """) { _, _ -> } 94 .failsToCompile() 95 .withErrorContaining(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD) 96 } 97 98 @Test 99 fun setterWithAssignableType() { 100 singleEntity(""" 101 @PrimaryKey 102 private int id; 103 public int getId() {return id;} 104 public void setId(Integer id) {} 105 """) { _, _ -> } 106 .compilesWithoutError() 107 } 108 109 @Test 110 fun getterWithAssignableType() { 111 singleEntity(""" 112 @PrimaryKey 113 private int id; 114 public Integer getId() {return id;} 115 public void setId(int id) {} 116 """) { _, _ -> } 117 .compilesWithoutError() 118 } 119 120 @Test 121 fun noSetter() { 122 singleEntity(""" 123 @PrimaryKey 124 private int id; 125 public int getId(){ return id; } 126 """) { _, _ -> } 127 .failsToCompile() 128 .withErrorContaining(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD) 129 } 130 131 @Test 132 fun tooManyGetters() { 133 singleEntity(""" 134 @PrimaryKey 135 private int id; 136 public void setId(int id) {} 137 public int getId(){ return id; } 138 public int id(){ return id; } 139 """) { _, _ -> } 140 .failsToCompile() 141 .withErrorContaining("getId, id") 142 } 143 144 @Test 145 fun tooManyGettersWithIgnore() { 146 singleEntity(""" 147 @PrimaryKey 148 private int id; 149 public void setId(int id) {} 150 public int getId(){ return id; } 151 @Ignore public int id(){ return id; } 152 """) { entity, _ -> 153 assertThat(entity.fields.first().getter.name, `is`("getId")) 154 }.compilesWithoutError() 155 } 156 157 @Test 158 fun tooManyGettersWithDifferentVisibility() { 159 singleEntity(""" 160 @PrimaryKey 161 private int id; 162 public void setId(int id) {} 163 public int getId(){ return id; } 164 protected int id(){ return id; } 165 """) { entity, _ -> 166 assertThat(entity.fields.first().getter.name, `is`("getId")) 167 }.compilesWithoutError() 168 } 169 170 @Test 171 fun tooManyGettersWithDifferentTypes() { 172 singleEntity(""" 173 @PrimaryKey 174 public int id; 175 public void setId(int id) {} 176 public int getId(){ return id; } 177 """) { entity, _ -> 178 assertThat(entity.fields.first().getter.name, `is`("id")) 179 assertThat(entity.fields.first().getter.callType, `is`(CallType.FIELD)) 180 }.compilesWithoutError() 181 } 182 183 @Test 184 fun tooManySetters() { 185 singleEntity(""" 186 @PrimaryKey 187 private int id; 188 public void setId(int id) {} 189 public void id(int id) {} 190 public int getId(){ return id; } 191 """) { _, _ -> } 192 .failsToCompile() 193 .withErrorContaining("setId, id") 194 } 195 196 @Test 197 fun tooManySettersWithIgnore() { 198 singleEntity(""" 199 @PrimaryKey 200 private int id; 201 public void setId(int id) {} 202 @Ignore public void id(int id) {} 203 public int getId(){ return id; } 204 """) { entity, _ -> 205 assertThat(entity.fields.first().setter.name, `is`("setId")) 206 }.compilesWithoutError() 207 } 208 209 @Test 210 fun tooManySettersWithDifferentVisibility() { 211 singleEntity(""" 212 @PrimaryKey 213 private int id; 214 public void setId(int id) {} 215 protected void id(int id) {} 216 public int getId(){ return id; } 217 """) { entity, _ -> 218 assertThat(entity.fields.first().setter.name, `is`("setId")) 219 }.compilesWithoutError() 220 } 221 222 @Test 223 fun tooManySettersWithDifferentTypes() { 224 singleEntity(""" 225 @PrimaryKey 226 public int id; 227 public void setId(int id) {} 228 public int getId(){ return id; } 229 """) { entity, _ -> 230 assertThat(entity.fields.first().setter.name, `is`("id")) 231 assertThat(entity.fields.first().setter.callType, `is`(CallType.FIELD)) 232 }.compilesWithoutError() 233 } 234 235 @Test 236 fun preferPublicOverProtected() { 237 singleEntity(""" 238 @PrimaryKey 239 int id; 240 public void setId(int id) {} 241 public int getId(){ return id; } 242 """) { entity, _ -> 243 assertThat(entity.fields.first().setter.name, `is`("setId")) 244 assertThat(entity.fields.first().getter.name, `is`("getId")) 245 }.compilesWithoutError() 246 } 247 248 @Test 249 fun customName() { 250 singleEntity(""" 251 @PrimaryKey 252 int x; 253 """, hashMapOf(Pair("tableName", "\"foo_table\""))) { entity, _ -> 254 assertThat(entity.tableName, `is`("foo_table")) 255 }.compilesWithoutError() 256 } 257 258 @Test 259 fun emptyCustomName() { 260 singleEntity(""" 261 @PrimaryKey 262 int x; 263 """, hashMapOf(Pair("tableName", "\" \""))) { _, _ -> 264 }.failsToCompile().withErrorContaining(ProcessorErrors.ENTITY_TABLE_NAME_CANNOT_BE_EMPTY) 265 } 266 267 @Test 268 fun missingPrimaryKey() { 269 singleEntity(""" 270 """) { _, _ -> 271 }.failsToCompile() 272 .withErrorContaining(ProcessorErrors.MISSING_PRIMARY_KEY) 273 } 274 275 @Test 276 fun missingColumnAdapter() { 277 singleEntity(""" 278 @PrimaryKey 279 public java.util.Date myDate; 280 """) { _, _ -> 281 282 }.failsToCompile().withErrorContaining(ProcessorErrors.CANNOT_FIND_COLUMN_TYPE_ADAPTER) 283 } 284 285 @Test 286 fun dropSubPrimaryKey() { 287 singleEntity( 288 """ 289 @PrimaryKey 290 int id; 291 @Embedded 292 Point myPoint; 293 static class Point { 294 @PrimaryKey 295 int x; 296 int y; 297 } 298 """ 299 ) { entity, _ -> 300 assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id"))) 301 }.compilesWithoutError() 302 .withWarningCount(1) 303 .withWarningContaining(ProcessorErrors.embeddedPrimaryKeyIsDropped( 304 "foo.bar.MyEntity", "x")) 305 } 306 307 @Test 308 fun ignoreDropSubPrimaryKey() { 309 singleEntity( 310 """ 311 @PrimaryKey 312 int id; 313 @Embedded 314 @SuppressWarnings(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED) 315 Point myPoint; 316 static class Point { 317 @PrimaryKey 318 int x; 319 int y; 320 } 321 """ 322 ) { entity, _ -> 323 assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id"))) 324 }.compilesWithoutError().withWarningCount(0) 325 } 326 327 @Test 328 fun notNull() { 329 singleEntity( 330 """ 331 @PrimaryKey int id; 332 @NonNull public String name; 333 """ 334 ) { entity, _ -> 335 val field = fieldsByName(entity, "name").first() 336 assertThat(field.name, `is`("name")) 337 assertThat(field.columnName, `is`("name")) 338 assertThat(field.nonNull, `is`(true)) 339 }.compilesWithoutError() 340 } 341 342 private fun fieldsByName(entity : Pojo, vararg fieldNames : String) : List<Field> { 343 return fieldNames 344 .map { name -> entity.fields.find { it.name == name } } 345 .filterNotNull() 346 } 347 348 @Test 349 fun index_simple() { 350 val annotation = mapOf( 351 "indices" to """@Index("foo")""" 352 ) 353 singleEntity( 354 """ 355 @PrimaryKey 356 public int id; 357 public String foo; 358 """ 359 , annotation) { entity, _ -> 360 assertThat(entity.indices, `is`( 361 listOf(Index(name = "index_MyEntity_foo", 362 unique = false, 363 fields = fieldsByName(entity, "foo"))))) 364 }.compilesWithoutError() 365 } 366 367 @Test 368 fun index_fromField() { 369 singleEntity( 370 """ 371 @PrimaryKey 372 public int id; 373 @ColumnInfo(index = true) 374 public String foo; 375 """) { entity, _ -> 376 assertThat(entity.indices, `is`( 377 listOf(Index(name = "index_MyEntity_foo", 378 unique = false, 379 fields = fieldsByName(entity, "foo"))) 380 )) 381 }.compilesWithoutError() 382 } 383 384 @Test 385 fun index_multiColumn() { 386 val annotation = mapOf( 387 "indices" to """@Index({"foo", "id"})""" 388 ) 389 singleEntity( 390 """ 391 @PrimaryKey 392 public int id; 393 public String foo; 394 """ 395 , annotation) { entity, _ -> 396 assertThat(entity.indices, `is`( 397 listOf(Index(name = "index_MyEntity_foo_id", 398 unique = false, 399 fields = fieldsByName(entity, "foo", "id"))) 400 )) 401 }.compilesWithoutError() 402 } 403 404 @Test 405 fun index_multiple() { 406 val annotation = mapOf( 407 "indices" to """{@Index({"foo", "id"}), @Index({"bar_column", "foo"})}""" 408 ) 409 singleEntity( 410 """ 411 @PrimaryKey 412 public int id; 413 public String foo; 414 @ColumnInfo(name = "bar_column") 415 public String bar; 416 """ 417 , annotation) { entity, _ -> 418 assertThat(entity.indices, `is`( 419 listOf(Index(name = "index_MyEntity_foo_id", 420 unique = false, 421 fields = fieldsByName(entity, "foo", "id")), 422 Index(name = "index_MyEntity_bar_column_foo", 423 unique = false, 424 fields = fieldsByName(entity, "bar", "foo"))) 425 )) 426 }.compilesWithoutError() 427 } 428 429 @Test 430 fun index_unique() { 431 val annotation = mapOf( 432 "indices" to """@Index(value = {"foo", "id"}, unique = true)""" 433 ) 434 singleEntity( 435 """ 436 @PrimaryKey 437 public int id; 438 public String foo; 439 """ 440 , annotation) { entity, _ -> 441 assertThat(entity.indices, `is`( 442 listOf(Index(name = "index_MyEntity_foo_id", 443 unique = true, 444 fields = fieldsByName(entity, "foo", "id"))) 445 )) 446 }.compilesWithoutError() 447 } 448 449 @Test 450 fun index_customName() { 451 val annotation = mapOf( 452 "indices" to """@Index(value = {"foo"}, name = "myName")""" 453 ) 454 singleEntity( 455 """ 456 @PrimaryKey 457 public int id; 458 public String foo; 459 """ 460 , annotation) { entity, _ -> 461 assertThat(entity.indices, `is`( 462 listOf(Index(name = "myName", 463 unique = false, 464 fields = fieldsByName(entity, "foo"))) 465 )) 466 }.compilesWithoutError() 467 } 468 469 @Test 470 fun index_customTableName() { 471 val annotation = mapOf( 472 "tableName" to "\"MyTable\"", 473 "indices" to """@Index(value = {"foo"})""" 474 ) 475 singleEntity( 476 """ 477 @PrimaryKey 478 public int id; 479 public String foo; 480 """ 481 , annotation) { entity, _ -> 482 assertThat(entity.indices, `is`( 483 listOf(Index(name = "index_MyTable_foo", 484 unique = false, 485 fields = fieldsByName(entity, "foo"))) 486 )) 487 }.compilesWithoutError() 488 } 489 490 @Test 491 fun index_empty() { 492 val annotation = mapOf( 493 "indices" to """@Index({})""" 494 ) 495 singleEntity( 496 """ 497 @PrimaryKey 498 public int id; 499 public String foo; 500 """ 501 , annotation) { _, _ -> 502 }.failsToCompile().withErrorContaining( 503 ProcessorErrors.INDEX_COLUMNS_CANNOT_BE_EMPTY 504 ) 505 } 506 507 @Test 508 fun index_missingColumn() { 509 val annotation = mapOf( 510 "indices" to """@Index({"foo", "bar"})""" 511 ) 512 singleEntity( 513 """ 514 @PrimaryKey 515 public int id; 516 public String foo; 517 """ 518 , annotation) { _, _ -> 519 }.failsToCompile().withErrorContaining( 520 ProcessorErrors.indexColumnDoesNotExist("bar", listOf("id, foo")) 521 ) 522 } 523 524 @Test 525 fun index_nameConflict() { 526 val annotation = mapOf( 527 "indices" to """@Index({"foo"})""" 528 ) 529 singleEntity( 530 """ 531 @PrimaryKey 532 public int id; 533 @ColumnInfo(index = true) 534 public String foo; 535 """ 536 , annotation) { _, _ -> 537 }.failsToCompile().withErrorContaining( 538 ProcessorErrors.duplicateIndexInEntity("index_MyEntity_foo") 539 ) 540 } 541 542 @Test 543 fun index_droppedParentFieldIndex() { 544 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 545 """ 546 package foo.bar; 547 import android.arch.persistence.room.*; 548 public class Base { 549 @PrimaryKey 550 long baseId; 551 @ColumnInfo(index = true) 552 String name; 553 String lastName; 554 } 555 """) 556 singleEntity( 557 """ 558 @PrimaryKey 559 public int id; 560 """, baseClass = "foo.bar.Base", jfos = listOf(parent)) { entity, _ -> 561 assertThat(entity.indices.isEmpty(), `is`(true)) 562 }.compilesWithoutError() 563 .withWarningContaining( 564 ProcessorErrors.droppedSuperClassFieldIndex( 565 fieldName = "name", 566 childEntity = "foo.bar.MyEntity", 567 superEntity = "foo.bar.Base") 568 ) 569 } 570 571 @Test 572 fun index_keptGrandParentEntityIndex() { 573 val grandParent = JavaFileObjects.forSourceLines("foo.bar.Base", 574 """ 575 package foo.bar; 576 import android.arch.persistence.room.*; 577 @Entity(indices = @Index({"name", "lastName"})) 578 public class Base { 579 @PrimaryKey 580 long baseId; 581 String name, lastName; 582 } 583 """) 584 val parent = JavaFileObjects.forSourceLines("foo.bar.Parent", 585 """ 586 package foo.bar; 587 import android.arch.persistence.room.*; 588 589 public class Parent extends Base { 590 String iHaveAField; 591 } 592 """) 593 singleEntity( 594 """ 595 @PrimaryKey 596 public int id; 597 """, 598 baseClass = "foo.bar.Parent", 599 attributes = hashMapOf("inheritSuperIndices" to "true"), 600 jfos = listOf(parent, grandParent)) { 601 entity, _ -> 602 assertThat(entity.indices.size, `is`(1)) 603 assertThat(entity.indices.first(), 604 `is`(Index(name = "index_MyEntity_name_lastName", 605 unique = false, 606 fields = fieldsByName(entity, "name", "lastName")))) 607 }.compilesWithoutError().withWarningCount(0) 608 } 609 610 @Test 611 fun index_keptParentEntityIndex() { 612 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 613 """ 614 package foo.bar; 615 import android.arch.persistence.room.*; 616 @Entity(indices = @Index({"name", "lastName"})) 617 public class Base { 618 @PrimaryKey 619 long baseId; 620 String name, lastName; 621 } 622 """) 623 singleEntity( 624 """ 625 @PrimaryKey 626 public int id; 627 """, 628 baseClass = "foo.bar.Base", 629 attributes = hashMapOf("inheritSuperIndices" to "true"), 630 jfos = listOf(parent)) { entity, _ -> 631 assertThat(entity.indices.size, `is`(1)) 632 assertThat(entity.indices.first(), 633 `is`(Index(name = "index_MyEntity_name_lastName", 634 unique = false, 635 fields = fieldsByName(entity, "name", "lastName")))) 636 }.compilesWithoutError().withWarningCount(0) 637 } 638 639 @Test 640 fun index_keptParentFieldIndex() { 641 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 642 """ 643 package foo.bar; 644 import android.arch.persistence.room.*; 645 public class Base { 646 @PrimaryKey 647 long baseId; 648 @ColumnInfo(index = true) 649 String name; 650 String lastName; 651 } 652 """) 653 singleEntity( 654 """ 655 @PrimaryKey 656 public int id; 657 """, 658 baseClass = "foo.bar.Base", 659 attributes = hashMapOf("inheritSuperIndices" to "true"), 660 jfos = listOf(parent)) { entity, _ -> 661 assertThat(entity.indices.size, `is`(1)) 662 assertThat(entity.indices.first(), 663 `is`(Index(name = "index_MyEntity_name", 664 unique = false, 665 fields = fieldsByName(entity, "name")))) 666 }.compilesWithoutError().withWarningCount(0) 667 668 } 669 670 @Test 671 fun index_droppedGrandParentEntityIndex() { 672 val grandParent = JavaFileObjects.forSourceLines("foo.bar.Base", 673 """ 674 package foo.bar; 675 import android.arch.persistence.room.*; 676 @Entity(indices = @Index({"name", "lastName"})) 677 public class Base { 678 @PrimaryKey 679 long baseId; 680 String name, lastName; 681 } 682 """) 683 val parent = JavaFileObjects.forSourceLines("foo.bar.Parent", 684 """ 685 package foo.bar; 686 import android.arch.persistence.room.*; 687 688 public class Parent extends Base { 689 String iHaveAField; 690 } 691 """) 692 singleEntity( 693 """ 694 @PrimaryKey 695 public int id; 696 """, baseClass = "foo.bar.Parent", jfos = listOf(parent, grandParent)) { 697 entity, _ -> 698 assertThat(entity.indices.isEmpty(), `is`(true)) 699 }.compilesWithoutError() 700 .withWarningContaining( 701 ProcessorErrors.droppedSuperClassIndex( 702 childEntity = "foo.bar.MyEntity", 703 superEntity = "foo.bar.Base") 704 ) 705 } 706 707 @Test 708 fun index_droppedParentEntityIndex() { 709 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 710 """ 711 package foo.bar; 712 import android.arch.persistence.room.*; 713 @Entity(indices = @Index({"name", "lastName"})) 714 public class Base { 715 @PrimaryKey 716 long baseId; 717 String name, lastName; 718 } 719 """) 720 singleEntity( 721 """ 722 @PrimaryKey 723 public int id; 724 """, baseClass = "foo.bar.Base", jfos = listOf(parent)) { entity, _ -> 725 assertThat(entity.indices.isEmpty(), `is`(true)) 726 }.compilesWithoutError() 727 .withWarningContaining( 728 ProcessorErrors.droppedSuperClassIndex( 729 childEntity = "foo.bar.MyEntity", 730 superEntity = "foo.bar.Base") 731 ) 732 } 733 734 @Test 735 fun index_droppedEmbeddedEntityIndex() { 736 singleEntity( 737 """ 738 @PrimaryKey 739 public int id; 740 @Embedded 741 public Foo foo; 742 @Entity(indices = {@Index("a")}) 743 static class Foo { 744 @PrimaryKey 745 @ColumnInfo(name = "foo_id") 746 int id; 747 @ColumnInfo(index = true) 748 public int a; 749 } 750 """) { entity, _ -> 751 assertThat(entity.indices.isEmpty(), `is`(true)) 752 }.compilesWithoutError() 753 .withWarningContaining( 754 ProcessorErrors.droppedEmbeddedIndex( 755 entityName = "foo.bar.MyEntity.Foo", 756 fieldPath = "foo", 757 grandParent = "foo.bar.MyEntity") 758 ) 759 } 760 761 @Test 762 fun index_onEmbeddedField() { 763 singleEntity( 764 """ 765 @PrimaryKey 766 public int id; 767 @Embedded 768 @ColumnInfo(index = true) 769 public Foo foo; 770 static class Foo { 771 @ColumnInfo(index = true) 772 public int a; 773 } 774 """) { entity, _ -> 775 assertThat(entity.indices.isEmpty(), `is`(true)) 776 }.failsToCompile().withErrorContaining( 777 ProcessorErrors.CANNOT_USE_MORE_THAN_ONE_POJO_FIELD_ANNOTATION 778 ) 779 } 780 781 @Test 782 fun index_droppedEmbeddedFieldIndex() { 783 singleEntity( 784 """ 785 @PrimaryKey 786 public int id; 787 @Embedded 788 public Foo foo; 789 static class Foo { 790 @ColumnInfo(index = true) 791 public int a; 792 } 793 """) { entity, _ -> 794 assertThat(entity.indices.isEmpty(), `is`(true)) 795 }.compilesWithoutError() 796 .withWarningContaining( 797 ProcessorErrors.droppedEmbeddedFieldIndex("foo > a", "foo.bar.MyEntity") 798 ) 799 } 800 801 @Test 802 fun index_referenceEmbeddedField() { 803 singleEntity( 804 """ 805 @PrimaryKey 806 public int id; 807 @Embedded 808 public Foo foo; 809 static class Foo { 810 public int a; 811 } 812 """, attributes = mapOf("indices" to "@Index(\"a\")")) { entity, _ -> 813 assertThat(entity.indices.size, `is`(1)) 814 assertThat(entity.indices.first(), `is`( 815 Index( 816 name = "index_MyEntity_a", 817 unique = false, 818 fields = fieldsByName(entity, "a") 819 ) 820 )) 821 }.compilesWithoutError() 822 } 823 824 @Test 825 fun primaryKey_definedInBothWays() { 826 singleEntity( 827 """ 828 public int id; 829 @PrimaryKey 830 public String foo; 831 """, 832 attributes = mapOf("primaryKeys" to "\"id\"")) { _, _ -> 833 }.failsToCompile().withErrorContaining( 834 ProcessorErrors.multiplePrimaryKeyAnnotations( 835 listOf("PrimaryKey[id]", "PrimaryKey[foo]") 836 )) 837 } 838 839 @Test 840 fun primaryKey_badColumnName() { 841 singleEntity( 842 """ 843 public int id; 844 """, 845 attributes = mapOf("primaryKeys" to "\"foo\"")) { _, _ -> 846 }.failsToCompile().withErrorContaining( 847 ProcessorErrors.primaryKeyColumnDoesNotExist("foo", listOf("id"))) 848 } 849 850 @Test 851 fun primaryKey_multipleAnnotations() { 852 singleEntity(""" 853 @PrimaryKey 854 int x; 855 @PrimaryKey 856 int y; 857 """) { entity, _ -> 858 assertThat(entity.primaryKey.fields.isEmpty(), `is`(true)) 859 }.failsToCompile() 860 .withErrorContaining( 861 ProcessorErrors.multiplePrimaryKeyAnnotations( 862 listOf("PrimaryKey[x]", "PrimaryKey[y]"))) 863 } 864 865 @Test 866 fun primaryKey_fromParentField() { 867 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 868 """ 869 package foo.bar; 870 import android.arch.persistence.room.*; 871 public class Base { 872 @PrimaryKey 873 long baseId; 874 String name, lastName; 875 } 876 """) 877 singleEntity( 878 """ 879 public int id; 880 """, 881 baseClass = "foo.bar.Base", 882 jfos = listOf(parent)) { entity, _ -> 883 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("baseId")) 884 885 }.compilesWithoutError().withWarningCount(0) 886 } 887 888 @Test 889 fun primaryKey_fromParentEntity() { 890 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 891 """ 892 package foo.bar; 893 import android.arch.persistence.room.*; 894 @Entity(primaryKeys = "baseId") 895 public class Base { 896 long baseId; 897 String name, lastName; 898 } 899 """) 900 singleEntity( 901 """ 902 public int id; 903 """, 904 baseClass = "foo.bar.Base", 905 jfos = listOf(parent)) { entity, _ -> 906 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("baseId")) 907 }.compilesWithoutError().withWarningCount(0) 908 } 909 910 @Test 911 fun primaryKey_overrideFromParentField() { 912 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 913 """ 914 package foo.bar; 915 import android.arch.persistence.room.*; 916 public class Base { 917 @PrimaryKey 918 long baseId; 919 String name, lastName; 920 } 921 """) 922 singleEntity( 923 """ 924 @PrimaryKey 925 public int id; 926 """, 927 baseClass = "foo.bar.Base", 928 jfos = listOf(parent)) { entity, _ -> 929 assertThat(entity.primaryKey.fields.size, `is`(1)) 930 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 931 assertThat(entity.primaryKey.autoGenerateId, `is`(false)) 932 }.compilesWithoutError().withNoteContaining( 933 "PrimaryKey[baseId] is overridden by PrimaryKey[id]" 934 ) 935 } 936 937 @Test 938 fun primaryKey_overrideFromParentEntityViaField() { 939 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 940 """ 941 package foo.bar; 942 import android.arch.persistence.room.*; 943 @Entity(primaryKeys = "baseId") 944 public class Base { 945 long baseId; 946 String name, lastName; 947 } 948 """) 949 singleEntity( 950 """ 951 @PrimaryKey 952 public int id; 953 """, 954 baseClass = "foo.bar.Base", 955 jfos = listOf(parent)) { entity, _ -> 956 assertThat(entity.primaryKey.fields.size, `is`(1)) 957 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 958 }.compilesWithoutError().withNoteContaining( 959 "PrimaryKey[baseId] is overridden by PrimaryKey[id]" 960 ) 961 } 962 963 @Test 964 fun primaryKey_overrideFromParentEntityViaEntity() { 965 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 966 """ 967 package foo.bar; 968 import android.arch.persistence.room.*; 969 @Entity(primaryKeys = "baseId") 970 public class Base { 971 long baseId; 972 String name, lastName; 973 } 974 """) 975 singleEntity( 976 """ 977 public int id; 978 """, 979 baseClass = "foo.bar.Base", 980 jfos = listOf(parent), 981 attributes = mapOf("primaryKeys" to "\"id\"")) { entity, _ -> 982 assertThat(entity.primaryKey.fields.size, `is`(1)) 983 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 984 assertThat(entity.primaryKey.autoGenerateId, `is`(false)) 985 }.compilesWithoutError().withNoteContaining( 986 "PrimaryKey[baseId] is overridden by PrimaryKey[id]" 987 ) 988 } 989 990 @Test 991 fun primaryKey_autoGenerate() { 992 listOf("long", "Long", "Integer", "int").forEach { type -> 993 singleEntity( 994 """ 995 @PrimaryKey(autoGenerate = true) 996 public $type id; 997 """) { entity, _ -> 998 assertThat(entity.primaryKey.fields.size, `is`(1)) 999 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 1000 assertThat(entity.primaryKey.autoGenerateId, `is`(true)) 1001 }.compilesWithoutError() 1002 } 1003 } 1004 1005 @Test 1006 fun primaryKey_autoGenerateBadType() { 1007 listOf("String", "float", "Float", "Double", "double").forEach { type -> 1008 singleEntity( 1009 """ 1010 @PrimaryKey(autoGenerate = true) 1011 public $type id; 1012 """) { entity, _ -> 1013 assertThat(entity.primaryKey.fields.size, `is`(1)) 1014 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 1015 assertThat(entity.primaryKey.autoGenerateId, `is`(true)) 1016 }.failsToCompile().withErrorContaining( 1017 ProcessorErrors.AUTO_INCREMENTED_PRIMARY_KEY_IS_NOT_INT) 1018 } 1019 } 1020 1021 @Test 1022 fun primaryKey_embedded(){ 1023 singleEntity( 1024 """ 1025 public int id; 1026 1027 @Embedded(prefix = "bar_") 1028 @PrimaryKey 1029 @NonNull 1030 public Foo foo; 1031 1032 static class Foo { 1033 public int a; 1034 public int b; 1035 } 1036 """) { entity, _ -> 1037 assertThat(entity.primaryKey.fields.map { it.columnName }, 1038 `is`(listOf("bar_a", "bar_b"))) 1039 }.compilesWithoutError().withWarningCount(0) 1040 } 1041 1042 @Test 1043 fun primaryKey_embeddedInherited(){ 1044 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 1045 """ 1046 package foo.bar; 1047 import android.support.annotation.NonNull; 1048 import android.arch.persistence.room.*; 1049 1050 public class Base { 1051 long baseId; 1052 String name, lastName; 1053 @Embedded(prefix = "bar_") 1054 @PrimaryKey 1055 @NonNull 1056 public Foo foo; 1057 1058 static class Foo { 1059 public int a; 1060 public int b; 1061 } 1062 } 1063 """) 1064 singleEntity( 1065 """ 1066 public int id; 1067 """, 1068 baseClass = "foo.bar.Base", 1069 jfos = listOf(parent)) { entity, _ -> 1070 assertThat(entity.primaryKey.fields.map { it.columnName }, 1071 `is`(listOf("bar_a", "bar_b"))) 1072 }.compilesWithoutError().withWarningCount(0) 1073 } 1074 1075 @Test 1076 fun primaryKey_overrideViaEmbedded() { 1077 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 1078 """ 1079 package foo.bar; 1080 import android.arch.persistence.room.*; 1081 1082 @Entity(primaryKeys = "baseId") 1083 public class Base { 1084 long baseId; 1085 String name, lastName; 1086 } 1087 """) 1088 singleEntity( 1089 """ 1090 public int id; 1091 @Embedded(prefix = "bar_") 1092 @PrimaryKey 1093 @NonNull 1094 public Foo foo; 1095 1096 static class Foo { 1097 public int a; 1098 public int b; 1099 } 1100 """, 1101 baseClass = "foo.bar.Base", 1102 jfos = listOf(parent)) { entity, _ -> 1103 assertThat(entity.primaryKey.fields.map { it.columnName }, 1104 `is`(listOf("bar_a", "bar_b"))) 1105 }.compilesWithoutError().withNoteContaining( 1106 "PrimaryKey[baseId] is overridden by PrimaryKey[foo > a, foo > b]") 1107 } 1108 1109 @Test 1110 fun primaryKey_overrideEmbedded() { 1111 val parent = JavaFileObjects.forSourceLines("foo.bar.Base", 1112 """ 1113 package foo.bar; 1114 import android.support.annotation.NonNull; 1115 import android.arch.persistence.room.*; 1116 1117 public class Base { 1118 long baseId; 1119 String name, lastName; 1120 @Embedded(prefix = "bar_") 1121 @PrimaryKey 1122 @NonNull 1123 public Foo foo; 1124 1125 static class Foo { 1126 public int a; 1127 public int b; 1128 } 1129 } 1130 """) 1131 singleEntity( 1132 """ 1133 @PrimaryKey 1134 public int id; 1135 """, 1136 baseClass = "foo.bar.Base", 1137 jfos = listOf(parent)) { entity, _ -> 1138 assertThat(entity.primaryKey.fields.map { it.columnName }, 1139 `is`(listOf("id"))) 1140 }.compilesWithoutError().withNoteContaining( 1141 "PrimaryKey[foo > a, foo > b] is overridden by PrimaryKey[id]") 1142 } 1143 1144 @Test 1145 fun primaryKey_NonNull() { 1146 singleEntity( 1147 """ 1148 @PrimaryKey 1149 @NonNull 1150 public String id; 1151 """) { entity, _ -> 1152 assertThat(entity.primaryKey.fields.size, `is`(1)) 1153 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 1154 }.compilesWithoutError() 1155 } 1156 1157 @Test 1158 fun primaryKey_Nullable() { 1159 singleEntity( 1160 """ 1161 @PrimaryKey 1162 public String id; 1163 """) { entity, _ -> 1164 assertThat(entity.primaryKey.fields.size, `is`(1)) 1165 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id")) 1166 }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL) 1167 } 1168 1169 @Test 1170 fun primaryKey_MultipleNullable() { 1171 singleEntity( 1172 """ 1173 @PrimaryKey 1174 public String id; 1175 @PrimaryKey 1176 public String anotherId; 1177 """) { entity, _ -> 1178 }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL) 1179 } 1180 1181 @Test 1182 fun primaryKey_MultipleNullableAndNonNullable() { 1183 singleEntity( 1184 """ 1185 @PrimaryKey 1186 @NonNull 1187 public String id; 1188 @PrimaryKey 1189 public String anotherId; 1190 """) { entity, _ -> 1191 }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL) 1192 } 1193 1194 @Test 1195 fun primaryKey_definedAsAttributesNullable() { 1196 singleEntity( 1197 """ 1198 public int id; 1199 public String foo; 1200 """, 1201 attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")) { _, _ -> 1202 }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL) 1203 } 1204 1205 @Test 1206 fun primaryKey_definedAsAttributesNonNull() { 1207 singleEntity( 1208 """ 1209 public int id; 1210 @NonNull 1211 public String foo; 1212 """, 1213 attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")) { entity, _ -> 1214 assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id", "foo"))) 1215 }.compilesWithoutError() 1216 } 1217 1218 @Test 1219 fun relationInEntity() { 1220 singleEntity( 1221 """ 1222 @PrimaryKey 1223 int id; 1224 @Relation(parentColumn = "id", entityColumn = "uid") 1225 java.util.List<User> users; 1226 """, jfos = listOf(COMMON.USER) 1227 ) { _, _ -> 1228 }.failsToCompile().withErrorContaining(RELATION_IN_ENTITY) 1229 } 1230 1231 @Test 1232 fun foreignKey_invalidAction() { 1233 val annotation = mapOf( 1234 "foreignKeys" to """{@ForeignKey( 1235 entity = ${COMMON.USER_TYPE_NAME}.class, 1236 parentColumns = "lastName", 1237 childColumns = "name", 1238 onDelete = 101 1239 )}""".trimIndent() 1240 ) 1241 singleEntity( 1242 """ 1243 @PrimaryKey 1244 int id; 1245 String name; 1246 """, 1247 attributes = annotation, jfos = listOf(COMMON.USER) 1248 ){ _, _ -> 1249 }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_FOREIGN_KEY_ACTION) 1250 } 1251 1252 @Test 1253 fun foreignKey_badEntity() { 1254 val annotation = mapOf( 1255 "foreignKeys" to """{@ForeignKey( 1256 entity = dsa.class, 1257 parentColumns = "lastName", 1258 childColumns = "name" 1259 )}""".trimIndent() 1260 ) 1261 singleEntity( 1262 """ 1263 @PrimaryKey 1264 int id; 1265 String name; 1266 """, 1267 attributes = annotation, jfos = listOf(COMMON.USER) 1268 ){ _, _ -> 1269 }.failsToCompile().withErrorContaining("cannot find symbol") 1270 } 1271 1272 @Test 1273 fun foreignKey_notAnEntity() { 1274 val annotation = mapOf( 1275 "foreignKeys" to """{@ForeignKey( 1276 entity = ${COMMON.NOT_AN_ENTITY_TYPE_NAME}.class, 1277 parentColumns = "lastName", 1278 childColumns = "name" 1279 )}""".trimIndent() 1280 ) 1281 singleEntity( 1282 """ 1283 @PrimaryKey 1284 int id; 1285 String name; 1286 """, 1287 attributes = annotation, jfos = listOf(COMMON.NOT_AN_ENTITY) 1288 ){ _, _ -> 1289 }.failsToCompile().withErrorContaining(ProcessorErrors.foreignKeyNotAnEntity( 1290 COMMON.NOT_AN_ENTITY_TYPE_NAME.toString())) 1291 } 1292 1293 @Test 1294 fun foreignKey_invalidChildColumn() { 1295 val annotation = mapOf( 1296 "foreignKeys" to """{@ForeignKey( 1297 entity = ${COMMON.USER_TYPE_NAME}.class, 1298 parentColumns = "lastName", 1299 childColumns = "namex" 1300 )}""".trimIndent() 1301 ) 1302 singleEntity( 1303 """ 1304 @PrimaryKey 1305 int id; 1306 String name; 1307 """, 1308 attributes = annotation, jfos = listOf(COMMON.USER) 1309 ){ _, _ -> 1310 }.failsToCompile().withErrorContaining(ProcessorErrors.foreignKeyChildColumnDoesNotExist( 1311 "namex", listOf("id", "name"))) 1312 } 1313 1314 @Test 1315 fun foreignKey_columnCountMismatch() { 1316 val annotation = mapOf( 1317 "foreignKeys" to """{@ForeignKey( 1318 entity = ${COMMON.USER_TYPE_NAME}.class, 1319 parentColumns = "lastName", 1320 childColumns = {"name", "id"} 1321 )}""".trimIndent() 1322 ) 1323 singleEntity( 1324 """ 1325 @PrimaryKey 1326 int id; 1327 String name; 1328 """, 1329 attributes = annotation, jfos = listOf(COMMON.USER) 1330 ){ _, _ -> 1331 }.failsToCompile().withErrorContaining(ProcessorErrors.foreignKeyColumnNumberMismatch( 1332 listOf("name", "id"), listOf("lastName"))) 1333 } 1334 1335 @Test 1336 fun foreignKey_emptyChildColumns() { 1337 val annotation = mapOf( 1338 "foreignKeys" to """{@ForeignKey( 1339 entity = ${COMMON.USER_TYPE_NAME}.class, 1340 parentColumns = "lastName", 1341 childColumns = {} 1342 )}""".trimIndent() 1343 ) 1344 singleEntity( 1345 """ 1346 @PrimaryKey 1347 int id; 1348 String name; 1349 """, 1350 attributes = annotation, jfos = listOf(COMMON.USER) 1351 ){ _, _ -> 1352 }.failsToCompile().withErrorContaining(ProcessorErrors.FOREIGN_KEY_EMPTY_CHILD_COLUMN_LIST) 1353 } 1354 1355 @Test 1356 fun foreignKey_emptyParentColumns() { 1357 val annotation = mapOf( 1358 "foreignKeys" to """{@ForeignKey( 1359 entity = ${COMMON.USER_TYPE_NAME}.class, 1360 parentColumns = {}, 1361 childColumns = {"name"} 1362 )}""".trimIndent() 1363 ) 1364 singleEntity( 1365 """ 1366 @PrimaryKey 1367 int id; 1368 String name; 1369 """, 1370 attributes = annotation, jfos = listOf(COMMON.USER) 1371 ){ _, _ -> 1372 }.failsToCompile().withErrorContaining(ProcessorErrors.FOREIGN_KEY_EMPTY_PARENT_COLUMN_LIST) 1373 } 1374 1375 @Test 1376 fun foreignKey_simple() { 1377 val annotation = mapOf( 1378 "foreignKeys" to """{@ForeignKey( 1379 entity = ${COMMON.USER_TYPE_NAME}.class, 1380 parentColumns = "lastName", 1381 childColumns = "name", 1382 onDelete = ForeignKey.SET_NULL, 1383 onUpdate = ForeignKey.CASCADE, 1384 deferred = true 1385 )}""".trimIndent() 1386 ) 1387 singleEntity( 1388 """ 1389 @PrimaryKey 1390 int id; 1391 String name; 1392 """, 1393 attributes = annotation, jfos = listOf(COMMON.USER) 1394 ){ entity, _ -> 1395 assertThat(entity.foreignKeys.size, `is`(1)) 1396 val fKey = entity.foreignKeys.first() 1397 assertThat(fKey.parentTable, `is`("User")) 1398 assertThat(fKey.parentColumns, `is`(listOf("lastName"))) 1399 assertThat(fKey.deferred, `is`(true)) 1400 assertThat(fKey.childFields.size, `is`(1)) 1401 val field = fKey.childFields.first() 1402 assertThat(field.name, `is`("name")) 1403 }.compilesWithoutError() 1404 } 1405 1406 @Test 1407 fun foreignKey_dontDuplicationChildIndex_SingleColumn() { 1408 val annotation = mapOf( 1409 "foreignKeys" to """{@ForeignKey( 1410 entity = ${COMMON.USER_TYPE_NAME}.class, 1411 parentColumns = "lastName", 1412 childColumns = "name", 1413 onDelete = ForeignKey.SET_NULL, 1414 onUpdate = ForeignKey.CASCADE, 1415 deferred = true 1416 )}""".trimIndent(), 1417 "indices" to """@Index("name")""" 1418 ) 1419 singleEntity( 1420 """ 1421 @PrimaryKey 1422 int id; 1423 String name; 1424 """, 1425 attributes = annotation, jfos = listOf(COMMON.USER) 1426 ) { _, _ -> 1427 }.compilesWithoutWarnings() 1428 } 1429 1430 @Test 1431 fun foreignKey_dontDuplicationChildIndex_MultipleColumns() { 1432 val annotation = mapOf( 1433 "foreignKeys" to """{@ForeignKey( 1434 entity = ${COMMON.USER_TYPE_NAME}.class, 1435 parentColumns = {"lastName", "name"}, 1436 childColumns = {"lName", "name"}, 1437 onDelete = ForeignKey.SET_NULL, 1438 onUpdate = ForeignKey.CASCADE, 1439 deferred = true 1440 )}""".trimIndent(), 1441 "indices" to """@Index({"lName", "name"})""" 1442 ) 1443 singleEntity( 1444 """ 1445 @PrimaryKey 1446 int id; 1447 String name; 1448 String lName; 1449 """, 1450 attributes = annotation, jfos = listOf(COMMON.USER) 1451 ) { entity, _ -> 1452 assertThat(entity.indices.size, `is`(1)) 1453 }.compilesWithoutWarnings() 1454 } 1455 1456 @Test 1457 fun foreignKey_dontDuplicationChildIndex_WhenCovered() { 1458 val annotation = mapOf( 1459 "foreignKeys" to """{@ForeignKey( 1460 entity = ${COMMON.USER_TYPE_NAME}.class, 1461 parentColumns = {"lastName"}, 1462 childColumns = {"name"}, 1463 onDelete = ForeignKey.SET_NULL, 1464 onUpdate = ForeignKey.CASCADE, 1465 deferred = true 1466 )}""".trimIndent(), 1467 "indices" to """@Index({"name", "lName"})""" 1468 ) 1469 singleEntity( 1470 """ 1471 @PrimaryKey 1472 int id; 1473 String name; 1474 String lName; 1475 """, 1476 attributes = annotation, jfos = listOf(COMMON.USER) 1477 ) { entity, _ -> 1478 assertThat(entity.indices.size, `is`(1)) 1479 }.compilesWithoutWarnings() 1480 } 1481 1482 @Test 1483 fun foreignKey_warnMissingChildIndex() { 1484 val annotation = mapOf( 1485 "foreignKeys" to """{@ForeignKey( 1486 entity = ${COMMON.USER_TYPE_NAME}.class, 1487 parentColumns = "lastName", 1488 childColumns = "name", 1489 onDelete = ForeignKey.SET_NULL, 1490 onUpdate = ForeignKey.CASCADE, 1491 deferred = true 1492 )}""".trimIndent() 1493 ) 1494 singleEntity( 1495 """ 1496 @PrimaryKey 1497 int id; 1498 String name; 1499 """, 1500 attributes = annotation, jfos = listOf(COMMON.USER) 1501 ){ entity, _ -> 1502 assertThat(entity.indices, `is`(emptyList())) 1503 }.compilesWithoutError().withWarningContaining( 1504 ProcessorErrors.foreignKeyMissingIndexInChildColumn("name")) 1505 } 1506 1507 @Test 1508 fun foreignKey_warnMissingChildrenIndex() { 1509 val annotation = mapOf( 1510 "foreignKeys" to """{@ForeignKey( 1511 entity = ${COMMON.USER_TYPE_NAME}.class, 1512 parentColumns = {"lastName", "name"}, 1513 childColumns = {"lName", "name"} 1514 )}""".trimIndent() 1515 ) 1516 singleEntity( 1517 """ 1518 @PrimaryKey 1519 int id; 1520 String name; 1521 String lName; 1522 """, 1523 attributes = annotation, jfos = listOf(COMMON.USER) 1524 ){ entity, _ -> 1525 assertThat(entity.indices, `is`(emptyList())) 1526 }.compilesWithoutError().withWarningContaining( 1527 ProcessorErrors.foreignKeyMissingIndexInChildColumns(listOf("lName", "name"))) 1528 } 1529 1530 @Test 1531 fun foreignKey_dontIndexIfAlreadyPrimaryKey() { 1532 val annotation = mapOf( 1533 "foreignKeys" to """{@ForeignKey( 1534 entity = ${COMMON.USER_TYPE_NAME}.class, 1535 parentColumns = "lastName", 1536 childColumns = "id", 1537 onDelete = ForeignKey.SET_NULL, 1538 onUpdate = ForeignKey.CASCADE, 1539 deferred = true 1540 )}""".trimIndent() 1541 ) 1542 singleEntity( 1543 """ 1544 @PrimaryKey 1545 int id; 1546 String name; 1547 """, 1548 attributes = annotation, jfos = listOf(COMMON.USER) 1549 ){ entity, _ -> 1550 assertThat(entity.indices, `is`(emptyList())) 1551 }.compilesWithoutWarnings() 1552 } 1553} 1554