/src/spec/test/CodeGenerationASTTransformsTest.groovy

https://github.com/lhotari/groovy-core · Groovy · 1051 lines · 641 code · 163 blank · 247 comment · 73 complexity · 46702be10301aebbebe6be7b73b8273e MD5 · raw file

  1. /*
  2. * Copyright 2003-2014 the original author or authors.
  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. class CodeGenerationASTTransformsTest extends GroovyTestCase {
  17. // specification tests for the @ToString AST transformation
  18. void testToString() {
  19. assertScript '''
  20. // tag::tostring_import[]
  21. import groovy.transform.ToString
  22. // end::tostring_import[]
  23. // tag::tostring_simple[]
  24. @ToString
  25. class Person {
  26. String firstName
  27. String lastName
  28. }
  29. // end::tostring_simple[]
  30. // tag::tostring_simple_assert[]
  31. def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
  32. assert p.toString() == 'Person(Jack, Nicholson)'
  33. // end::tostring_simple_assert[]
  34. '''
  35. assertScript '''
  36. import groovy.transform.ToString
  37. // tag::tostring_example_includeNames[]
  38. @ToString(includeNames=true)
  39. class Person {
  40. String firstName
  41. String lastName
  42. }
  43. def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
  44. assert p.toString() == 'Person(firstName:Jack, lastName:Nicholson)'
  45. // end::tostring_example_includeNames[]
  46. '''
  47. assertScript '''
  48. import groovy.transform.ToString
  49. // tag::tostring_example_excludes[]
  50. @ToString(excludes=['firstName'])
  51. class Person {
  52. String firstName
  53. String lastName
  54. }
  55. def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
  56. assert p.toString() == 'Person(Nicholson)'
  57. // end::tostring_example_excludes[]
  58. '''
  59. assertScript '''
  60. import groovy.transform.ToString
  61. // tag::tostring_example_includes[]
  62. @ToString(includes=['lastName'])
  63. class Person {
  64. String firstName
  65. String lastName
  66. }
  67. def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
  68. assert p.toString() == 'Person(Nicholson)'
  69. // end::tostring_example_includes[]
  70. '''
  71. assertScript '''
  72. import groovy.transform.ToString
  73. // tag::tostring_example_includeFields[]
  74. @ToString(includeFields=true)
  75. class Person {
  76. String firstName
  77. String lastName
  78. private int age
  79. void test() {
  80. age = 42
  81. }
  82. }
  83. def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
  84. p.test()
  85. assert p.toString() == 'Person(Jack, Nicholson, 42)'
  86. // end::tostring_example_includeFields[]
  87. '''
  88. assertScript '''
  89. import groovy.transform.ToString
  90. // tag::tostring_example_includeSuper[]
  91. @ToString
  92. class Id { long id }
  93. @ToString(includeSuper=true)
  94. class Person extends Id {
  95. String firstName
  96. String lastName
  97. }
  98. def p = new Person(id:1, firstName: 'Jack', lastName: 'Nicholson')
  99. assert p.toString() == 'Person(Jack, Nicholson, Id(1))'
  100. // end::tostring_example_includeSuper[]
  101. '''
  102. assertScript '''
  103. import groovy.transform.ToString
  104. // tag::tostring_example_ignoreNulls[]
  105. @ToString(ignoreNulls=true)
  106. class Person {
  107. String firstName
  108. String lastName
  109. }
  110. def p = new Person(firstName: 'Jack')
  111. assert p.toString() == 'Person(Jack)'
  112. // end::tostring_example_ignoreNulls[]
  113. '''
  114. assertScript '''import groovy.transform.ToString
  115. // tag::tostring_example_cache[]
  116. @ToString(cache=true)
  117. class Person {
  118. String firstName
  119. String lastName
  120. }
  121. def p = new Person(firstName: 'Jack', lastName:'Nicholson')
  122. def s1 = p.toString()
  123. def s2 = p.toString()
  124. assert s1 == s2
  125. assert s1 == 'Person(Jack, Nicholson)'
  126. assert s1.is(s2) // same instance
  127. // end::tostring_example_cache[]
  128. '''
  129. assertScript '''package acme
  130. import groovy.transform.ToString
  131. // tag::tostring_example_includePackage[]
  132. @ToString(includePackage=true)
  133. class Person {
  134. String firstName
  135. String lastName
  136. }
  137. def p = new Person(firstName: 'Jack', lastName:'Nicholson')
  138. assert p.toString() == 'acme.Person(Jack, Nicholson)'
  139. // end::tostring_example_includePackage[]
  140. '''
  141. }
  142. void testEqualsAndHashCode() {
  143. assertScript '''
  144. // tag::equalshashcode[]
  145. import groovy.transform.EqualsAndHashCode
  146. @EqualsAndHashCode
  147. class Person {
  148. String firstName
  149. String lastName
  150. }
  151. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  152. def p2 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  153. assert p1==p2
  154. assert p1.hashCode() == p2.hashCode()
  155. // end::equalshashcode[]
  156. '''
  157. assertScript '''
  158. // tag::equalshashcode_example_excludes[]
  159. import groovy.transform.EqualsAndHashCode
  160. @EqualsAndHashCode(excludes=['firstName'])
  161. class Person {
  162. String firstName
  163. String lastName
  164. }
  165. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  166. def p2 = new Person(firstName: 'Bob', lastName: 'Nicholson')
  167. assert p1==p2
  168. assert p1.hashCode() == p2.hashCode()
  169. // end::equalshashcode_example_excludes[]
  170. '''
  171. assertScript '''
  172. // tag::equalshashcode_example_includes[]
  173. import groovy.transform.EqualsAndHashCode
  174. @EqualsAndHashCode(includes=['lastName'])
  175. class Person {
  176. String firstName
  177. String lastName
  178. }
  179. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  180. def p2 = new Person(firstName: 'Bob', lastName: 'Nicholson')
  181. assert p1==p2
  182. assert p1.hashCode() == p2.hashCode()
  183. // end::equalshashcode_example_includes[]
  184. '''
  185. assertScript '''
  186. // tag::equalshashcode_example_super[]
  187. import groovy.transform.EqualsAndHashCode
  188. @EqualsAndHashCode
  189. class Living {
  190. String race
  191. }
  192. @EqualsAndHashCode(callSuper=true)
  193. class Person extends Living {
  194. String firstName
  195. String lastName
  196. }
  197. def p1 = new Person(race:'Human', firstName: 'Jack', lastName: 'Nicholson')
  198. def p2 = new Person(race: 'Human beeing', firstName: 'Jack', lastName: 'Nicholson')
  199. assert p1!=p2
  200. assert p1.hashCode() != p2.hashCode()
  201. // end::equalshashcode_example_super[]
  202. '''
  203. }
  204. void testTupleConstructor() {
  205. assertScript '''
  206. // tag::tupleconstructor_simple[]
  207. import groovy.transform.TupleConstructor
  208. @TupleConstructor
  209. class Person {
  210. String firstName
  211. String lastName
  212. }
  213. // traditional map-style constructor
  214. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  215. // generated tuple constructor
  216. def p2 = new Person('Jack', 'Nicholson')
  217. // generated tuple constructor with default value for second property
  218. def p3 = new Person('Jack')
  219. // end::tupleconstructor_simple[]
  220. assert p1.firstName == p2.firstName
  221. assert p1.firstName == p3.firstName
  222. assert p1.lastName == p2.lastName
  223. assert p3.lastName == null
  224. '''
  225. assertScript '''
  226. // tag::tupleconstructor_example_excludes[]
  227. import groovy.transform.TupleConstructor
  228. @TupleConstructor(excludes=['lastName'])
  229. class Person {
  230. String firstName
  231. String lastName
  232. }
  233. // traditional map-style constructor
  234. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  235. // generated tuple constructor
  236. def p2 = new Person('Jack')
  237. try {
  238. // will fail because the second property is excluded
  239. def p3 = new Person('Jack', 'Nicholson')
  240. } catch (e) {
  241. assert e.message.contains ('Could not find matching constructor')
  242. }
  243. // end::tupleconstructor_example_excludes[]
  244. assert p1.firstName == p2.firstName
  245. assert p2.lastName == null
  246. '''
  247. assertScript '''
  248. // tag::tupleconstructor_example_includes[]
  249. import groovy.transform.TupleConstructor
  250. @TupleConstructor(includes=['firstName'])
  251. class Person {
  252. String firstName
  253. String lastName
  254. }
  255. // traditional map-style constructor
  256. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  257. // generated tuple constructor
  258. def p2 = new Person('Jack')
  259. try {
  260. // will fail because the second property is not included
  261. def p3 = new Person('Jack', 'Nicholson')
  262. } catch (e) {
  263. assert e.message.contains ('Could not find matching constructor')
  264. }
  265. // end::tupleconstructor_example_includes[]
  266. assert p1.firstName == p2.firstName
  267. assert p2.lastName == null
  268. '''
  269. assertScript '''
  270. // tag::tupleconstructor_example_includeFields[]
  271. import groovy.transform.TupleConstructor
  272. @TupleConstructor(includeFields=true)
  273. class Person {
  274. String firstName
  275. String lastName
  276. private String occupation
  277. public String toString() {
  278. "$firstName $lastName: $occupation"
  279. }
  280. }
  281. // traditional map-style constructor
  282. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson', occupation: 'Actor')
  283. // generated tuple constructor
  284. def p2 = new Person('Jack', 'Nicholson', 'Actor')
  285. assert p1.firstName == p2.firstName
  286. assert p1.lastName == p2.lastName
  287. assert p1.toString() == 'Jack Nicholson: Actor'
  288. assert p1.toString() == p2.toString()
  289. // end::tupleconstructor_example_includeFields[]
  290. '''
  291. assertScript '''
  292. // tag::tupleconstructor_example_includeSuperFields[]
  293. import groovy.transform.TupleConstructor
  294. class Base {
  295. protected String occupation
  296. public String occupation() { this.occupation }
  297. }
  298. @TupleConstructor(includeSuperFields=true)
  299. class Person extends Base {
  300. String firstName
  301. String lastName
  302. public String toString() {
  303. "$firstName $lastName: ${occupation()}"
  304. }
  305. }
  306. // traditional map-style constructor
  307. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson', occupation: 'Actor')
  308. // generated tuple constructor, super fields come first
  309. def p2 = new Person('Actor', 'Jack', 'Nicholson')
  310. assert p1.firstName == p2.firstName
  311. assert p1.lastName == p2.lastName
  312. assert p1.toString() == 'Jack Nicholson: Actor'
  313. assert p2.toString() == p1.toString()
  314. // end::tupleconstructor_example_includeSuperFields[]
  315. '''
  316. assertScript '''
  317. // tag::tupleconstructor_example_includeProperties[]
  318. import groovy.transform.TupleConstructor
  319. @TupleConstructor(includeProperties=false)
  320. class Person {
  321. String firstName
  322. String lastName
  323. }
  324. // traditional map-style constructor
  325. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  326. try {
  327. def p2 = new Person('Jack', 'Nicholson')
  328. } catch(e) {
  329. // will fail because properties are not included
  330. }
  331. // end::tupleconstructor_example_includeProperties[]
  332. '''
  333. assertScript '''
  334. // tag::tupleconstructor_example_includeSuperProperties[]
  335. import groovy.transform.TupleConstructor
  336. class Base {
  337. String occupation
  338. }
  339. @TupleConstructor(includeSuperProperties=true)
  340. class Person extends Base {
  341. String firstName
  342. String lastName
  343. public String toString() {
  344. "$firstName $lastName: $occupation"
  345. }
  346. }
  347. // traditional map-style constructor
  348. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  349. // generated tuple constructor, super properties come first
  350. def p2 = new Person('Actor', 'Jack', 'Nicholson')
  351. assert p1.firstName == p2.firstName
  352. assert p1.lastName == p2.lastName
  353. assert p1.toString() == 'Jack Nicholson: null'
  354. assert p2.toString() == 'Jack Nicholson: Actor'
  355. // end::tupleconstructor_example_includeSuperProperties[]
  356. '''
  357. assertScript '''
  358. // tag::tupleconstructor_example_includeSuperProperties[]
  359. import groovy.transform.TupleConstructor
  360. class Base {
  361. String occupation
  362. Base() {}
  363. Base(String job) { occupation = job?.toLowerCase() }
  364. }
  365. @TupleConstructor(includeSuperProperties = true, callSuper=true)
  366. class Person extends Base {
  367. String firstName
  368. String lastName
  369. public String toString() {
  370. "$firstName $lastName: $occupation"
  371. }
  372. }
  373. // traditional map-style constructor
  374. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  375. // generated tuple constructor, super properties come first
  376. def p2 = new Person('ACTOR', 'Jack', 'Nicholson')
  377. assert p1.firstName == p2.firstName
  378. assert p1.lastName == p2.lastName
  379. assert p1.toString() == 'Jack Nicholson: null'
  380. assert p2.toString() == 'Jack Nicholson: actor'
  381. // end::tupleconstructor_example_includeSuperProperties[]
  382. '''
  383. }
  384. void testCanonical() {
  385. assertScript '''
  386. // tag::canonical_simple[]
  387. import groovy.transform.Canonical
  388. @Canonical
  389. class Person {
  390. String firstName
  391. String lastName
  392. }
  393. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  394. assert p1.toString() == 'Person(Jack, Nicholson)' // Effect of @ToString
  395. def p2 = new Person('Jack','Nicholson') // Effect of @TupleConstructor
  396. assert p2.toString() == 'Person(Jack, Nicholson)'
  397. assert p1==p2 // Effect of @EqualsAndHashCode
  398. assert p1.hashCode()==p2.hashCode() // Effect of @EqualsAndHashCode
  399. // end::canonical_simple[]
  400. '''
  401. assertScript '''
  402. // tag::canonical_example_excludes[]
  403. import groovy.transform.Canonical
  404. @Canonical(excludes=['lastName'])
  405. class Person {
  406. String firstName
  407. String lastName
  408. }
  409. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  410. assert p1.toString() == 'Person(Jack)' // Effect of @ToString
  411. def p2 = new Person('Jack') // Effect of @TupleConstructor
  412. assert p2.toString() == 'Person(Jack)'
  413. assert p1==p2 // Effect of @EqualsAndHashCode
  414. assert p1.hashCode()==p2.hashCode() // Effect of @EqualsAndHashCode
  415. // end::canonical_example_excludes[]
  416. '''
  417. assertScript '''
  418. // tag::canonical_example_includes[]
  419. import groovy.transform.Canonical
  420. @Canonical(includes=['firstName'])
  421. class Person {
  422. String firstName
  423. String lastName
  424. }
  425. def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
  426. assert p1.toString() == 'Person(Jack)' // Effect of @ToString
  427. def p2 = new Person('Jack') // Effect of @TupleConstructor
  428. assert p2.toString() == 'Person(Jack)'
  429. assert p1==p2 // Effect of @EqualsAndHashCode
  430. assert p1.hashCode()==p2.hashCode() // Effect of @EqualsAndHashCode
  431. // end::canonical_example_includes[]
  432. '''
  433. }
  434. void testInheritConstructors() {
  435. assertScript '''
  436. // tag::inheritconstructors_simple[]
  437. import groovy.transform.InheritConstructors
  438. @InheritConstructors
  439. class CustomException extends Exception {}
  440. // all those are generated constructors
  441. new CustomException()
  442. new CustomException("A custom message")
  443. new CustomException("A custom message", new RuntimeException())
  444. new CustomException(new RuntimeException())
  445. // Java 7 only
  446. // new CustomException("A custom message", new RuntimeException(), false, true)
  447. // end::inheritconstructors_simple[]
  448. '''
  449. }
  450. void testIndexedProperty() {
  451. assertScript '''
  452. import groovy.transform.IndexedProperty
  453. // tag::indexedproperty_simple[]
  454. class SomeBean {
  455. @IndexedProperty String[] someArray = new String[2]
  456. @IndexedProperty List someList = []
  457. }
  458. def bean = new SomeBean()
  459. bean.setSomeArray(0, 'value')
  460. bean.setSomeList(0, 123)
  461. assert bean.someArray[0] == 'value'
  462. assert bean.someList == [123]
  463. // end::indexedproperty_simple[]
  464. '''
  465. }
  466. void testLazy() {
  467. assertScript '''
  468. // tag::lazy_simple[]
  469. class SomeBean {
  470. @Lazy LinkedList myField
  471. }
  472. // end::lazy_simple[]
  473. /* generates the following:
  474. // tag::lazy_simple_generated[]
  475. List $myField
  476. List getMyField() {
  477. if ($myField!=null) { return $myField }
  478. else {
  479. $myField = new LinkedList()
  480. return $myField
  481. }
  482. }
  483. // end::lazy_simple_generated[]
  484. */
  485. def bean = new SomeBean()
  486. assert bean.@$myField == null
  487. bean.myField // calls getter
  488. assert bean.@$myField == []
  489. '''
  490. assertScript '''
  491. // tag::lazy_default[]
  492. class SomeBean {
  493. @Lazy LinkedList myField = { ['a','b','c']}()
  494. }
  495. // end::lazy_default[]
  496. /* generates the following:
  497. // tag::lazy_default_generated[]
  498. List $myField
  499. List getMyField() {
  500. if ($myField!=null) { return $myField }
  501. else {
  502. $myField = { ['a','b','c']}()
  503. return $myField
  504. }
  505. }
  506. // end::lazy_default_generated[]
  507. */
  508. def bean = new SomeBean()
  509. assert bean.@$myField == null
  510. bean.myField // calls getter
  511. assert bean.@$myField == ['a','b','c']
  512. '''
  513. }
  514. void testNewify() {
  515. assertScript '''
  516. class Tree {
  517. List children
  518. Tree() {}
  519. Tree(Tree... children) { this.children = children?.toList() }
  520. }
  521. class Leaf extends Tree {
  522. String value
  523. Leaf(String value) { this.value = value}
  524. }
  525. // tag::newify_python[]
  526. @Newify([Tree,Leaf])
  527. class TreeBuilder {
  528. Tree tree = Tree(Leaf('A'),Leaf('B'),Tree(Leaf('C')))
  529. }
  530. // end::newify_python[]
  531. def builder = new TreeBuilder()
  532. '''
  533. assertScript '''
  534. class Tree {
  535. List children
  536. Tree() {}
  537. Tree(Tree... children) { this.children = children?.toList() }
  538. }
  539. class Leaf extends Tree {
  540. String value
  541. Leaf(String value) { this.value = value}
  542. }
  543. // tag::newify_ruby[]
  544. @Newify([Tree,Leaf])
  545. class TreeBuilder {
  546. Tree tree = Tree.new(Leaf.new('A'),Leaf.new('B'),Tree.new(Leaf.new('C')))
  547. }
  548. // end::newify_ruby[]
  549. def builder = new TreeBuilder()
  550. '''
  551. }
  552. void testCategoryTransformation() {
  553. assertScript '''
  554. // tag::oldstyle_category[]
  555. class TripleCategory {
  556. public static Integer triple(Integer self) {
  557. 3*self
  558. }
  559. }
  560. use (TripleCategory) {
  561. assert 9 == 3.triple()
  562. }
  563. // end::oldstyle_category[]
  564. '''
  565. assertScript '''
  566. // tag::newstyle_category[]
  567. @Category(Integer)
  568. class TripleCategory {
  569. public Integer triple() { 3*this }
  570. }
  571. use (TripleCategory) {
  572. assert 9 == 3.triple()
  573. }
  574. // end::newstyle_category[]
  575. '''
  576. }
  577. void testSortable() {
  578. assertScript '''
  579. // tag::sortable_simple[]
  580. import groovy.transform.Sortable
  581. @Sortable class Person {
  582. String first
  583. String last
  584. Integer born
  585. }
  586. // end::sortable_simple[]
  587. // tag::sortable_simple_usage[]
  588. def people = [
  589. new Person(first: 'Johnny', last: 'Depp', born: 1963),
  590. new Person(first: 'Keira', last: 'Knightley', born: 1985),
  591. new Person(first: 'Geoffrey', last: 'Rush', born: 1951),
  592. new Person(first: 'Orlando', last: 'Bloom', born: 1977)
  593. ]
  594. assert people[0] > people[2]
  595. assert people.sort()*.last == ['Rush', 'Depp', 'Knightley', 'Bloom']
  596. assert people.sort(false, Person.comparatorByFirst())*.first == ['Geoffrey', 'Johnny', 'Keira', 'Orlando']
  597. assert people.sort(false, Person.comparatorByLast())*.last == ['Bloom', 'Depp', 'Knightley', 'Rush']
  598. assert people.sort(false, Person.comparatorByBorn())*.last == ['Rush', 'Depp', 'Bloom', 'Knightley']
  599. // end::sortable_simple_usage[]
  600. /* generates the following:
  601. // tag::sortable_simple_generated_compareTo[]
  602. public int compareTo(java.lang.Object obj) {
  603. if (this.is(obj)) {
  604. return 0
  605. }
  606. if (!(obj instanceof Person)) {
  607. return -1
  608. }
  609. java.lang.Integer value = this.first <=> obj.first
  610. if (value != 0) {
  611. return value
  612. }
  613. value = this.last <=> obj.last
  614. if (value != 0) {
  615. return value
  616. }
  617. value = this.born <=> obj.born
  618. if (value != 0) {
  619. return value
  620. }
  621. return 0
  622. }
  623. // end::sortable_simple_generated_compareTo[]
  624. // tag::sortable_simple_generated_comparatorByFirst[]
  625. public int compare(java.lang.Object arg0, java.lang.Object arg1) {
  626. if (arg0 == arg1) {
  627. return 0
  628. }
  629. if (arg0 != null && arg1 == null) {
  630. return -1
  631. }
  632. if (arg0 == null && arg1 != null) {
  633. return 1
  634. }
  635. return arg0.first <=> arg1.first
  636. }
  637. // end::sortable_simple_generated_comparatorByFirst[]
  638. */
  639. '''
  640. assertScript '''
  641. import groovy.transform.Sortable
  642. // tag::sortable_custom[]
  643. @Sortable(includes='first,born') class Person {
  644. String last
  645. int born
  646. String first
  647. }
  648. // end::sortable_custom[]
  649. // tag::sortable_custom_usage[]
  650. def people = [
  651. new Person(first: 'Ben', last: 'Affleck', born: 1972),
  652. new Person(first: 'Ben', last: 'Stiller', born: 1965)
  653. ]
  654. assert people.sort()*.last == ['Stiller', 'Affleck']
  655. // end::sortable_custom_usage[]
  656. /* generates the following:
  657. // tag::sortable_custom_generated_compareTo[]
  658. public int compareTo(java.lang.Object obj) {
  659. if (this.is(obj)) {
  660. return 0
  661. }
  662. if (!(obj instanceof Person)) {
  663. return -1
  664. }
  665. java.lang.Integer value = this.first <=> obj.first
  666. if (value != 0) {
  667. return value
  668. }
  669. value = this.born <=> obj.born
  670. if (value != 0) {
  671. return value
  672. }
  673. return 0
  674. }
  675. // end::sortable_custom_generated_compareTo[]
  676. */
  677. '''
  678. }
  679. void testBuilderSimple() {
  680. assertScript '''
  681. // tag::builder_simple[]
  682. import groovy.transform.builder.*
  683. @Builder(builderStrategy=SimpleStrategy)
  684. class Person {
  685. String first
  686. String last
  687. Integer born
  688. }
  689. // end::builder_simple[]
  690. // tag::builder_simple_usage[]
  691. def p1 = new Person().setFirst('Johnny').setLast('Depp').setBorn(1963)
  692. assert "$p1.first $p1.last" == 'Johnny Depp'
  693. // end::builder_simple_usage[]
  694. // tag::builder_simple_alternatives[]
  695. def p2 = new Person(first: 'Keira', last: 'Knightley', born: 1985)
  696. def p3 = new Person().with {
  697. first = 'Geoffrey'
  698. last = 'Rush'
  699. born = 1951
  700. }
  701. // end::builder_simple_alternatives[]
  702. /* generates the following:
  703. // tag::builder_simple_generated_setter[]
  704. public Person setFirst(java.lang.String first) {
  705. this.first = first
  706. return this
  707. }
  708. // end::builder_simple_generated_setter[]
  709. */
  710. '''
  711. assertScript '''
  712. // tag::builder_simple_prefix[]
  713. import groovy.transform.builder.*
  714. @Builder(builderStrategy=SimpleStrategy, prefix="")
  715. class Person {
  716. String first
  717. String last
  718. Integer born
  719. }
  720. // end::builder_simple_prefix[]
  721. // tag::builder_simple_prefix_usage[]
  722. def p = new Person().first('Johnny').last('Depp').born(1963)
  723. assert "$p.first $p.last" == 'Johnny Depp'
  724. // end::builder_simple_prefix_usage[]
  725. '''
  726. }
  727. void testBuilderExternal() {
  728. assertScript '''
  729. // tag::builder_external_buildee[]
  730. class Person {
  731. String first
  732. String last
  733. int born
  734. }
  735. // end::builder_external_buildee[]
  736. // tag::builder_external[]
  737. import groovy.transform.builder.*
  738. @Builder(builderStrategy=ExternalStrategy, forClass=Person)
  739. class PersonBuilder { }
  740. def p = new PersonBuilder().first('Johnny').last('Depp').born(1963).build()
  741. assert "$p.first $p.last" == 'Johnny Depp'
  742. // end::builder_external[]
  743. /* generates the following build method:
  744. // tag::builder_external_generated_build[]
  745. public Person build() {
  746. Person _thePerson = new Person()
  747. _thePerson.first = first
  748. _thePerson.last = last
  749. _thePerson.born = born
  750. return _thePerson
  751. }
  752. // end::builder_external_generated_build[]
  753. */
  754. '''
  755. assertScript '''
  756. // tag::builder_external_java[]
  757. import groovy.transform.builder.*
  758. @Builder(builderStrategy=ExternalStrategy, forClass=javax.swing.DefaultButtonModel)
  759. class ButtonModelBuilder {}
  760. def model = new ButtonModelBuilder().enabled(true).pressed(true).armed(true).rollover(true).selected(true).build()
  761. assert model.isArmed()
  762. assert model.isPressed()
  763. assert model.isEnabled()
  764. assert model.isSelected()
  765. assert model.isRollover()
  766. // end::builder_external_java[]
  767. '''
  768. assertScript '''
  769. // tag::builder_external_custom[]
  770. import groovy.transform.builder.*
  771. import groovy.transform.Canonical
  772. @Canonical
  773. class Person {
  774. String first
  775. String last
  776. int born
  777. }
  778. @Builder(builderStrategy=ExternalStrategy, forClass=Person, includes=['first', 'last'], buildMethodName='create', prefix='with')
  779. class PersonBuilder { }
  780. def p = new PersonBuilder().withFirst('Johnny').withLast('Depp').create()
  781. assert "$p.first $p.last" == 'Johnny Depp'
  782. // end::builder_external_custom[]
  783. '''
  784. }
  785. void testBuilderDefault() {
  786. assertScript '''
  787. // tag::builder_default[]
  788. import groovy.transform.builder.Builder
  789. @Builder
  790. class Person {
  791. String firstName
  792. String lastName
  793. int age
  794. }
  795. def person = Person.builder().firstName("Robert").lastName("Lewandowski").age(21).build()
  796. assert person.firstName == "Robert"
  797. assert person.lastName == "Lewandowski"
  798. assert person.age == 21
  799. // end::builder_default[]
  800. '''
  801. assertScript '''
  802. // tag::builder_default_custom[]
  803. import groovy.transform.builder.Builder
  804. @Builder(buildMethodName='make', builderMethodName='maker', prefix='with', excludes='age')
  805. class Person {
  806. String firstName
  807. String lastName
  808. int age
  809. }
  810. def p = Person.maker().withFirstName("Robert").withLastName("Lewandowski").make()
  811. assert "$p.firstName $p.lastName" == "Robert Lewandowski"
  812. // end::builder_default_custom[]
  813. '''
  814. assertScript '''
  815. // tag::builder_default_methods[]
  816. import groovy.transform.builder.*
  817. import groovy.transform.*
  818. @ToString
  819. @Builder
  820. class Person {
  821. String first, last
  822. int born
  823. Person(){}
  824. @Builder(builderClassName='MovieBuilder', builderMethodName='byRoleBuilder')
  825. Person(String roleName) {
  826. if (roleName == 'Jack Sparrow') {
  827. this.first = 'Johnny'; this.last = 'Depp'; this.born = 1963
  828. }
  829. }
  830. @Builder(builderClassName='NameBuilder', builderMethodName='nameBuilder', prefix='having', buildMethodName='fullName')
  831. static String join(String first, String last) {
  832. first + ' ' + last
  833. }
  834. @Builder(builderClassName='SplitBuilder', builderMethodName='splitBuilder')
  835. static Person split(String name, int year) {
  836. def parts = name.split(' ')
  837. new Person(first: parts[0], last: parts[1], born: year)
  838. }
  839. }
  840. assert Person.splitBuilder().name("Johnny Depp").year(1963).build().toString() == 'Person(Johnny, Depp, 1963)'
  841. assert Person.byRoleBuilder().roleName("Jack Sparrow").build().toString() == 'Person(Johnny, Depp, 1963)'
  842. assert Person.nameBuilder().havingFirst('Johnny').havingLast('Depp').fullName() == 'Johnny Depp'
  843. assert Person.builder().first("Johnny").last('Depp').born(1963).build().toString() == 'Person(Johnny, Depp, 1963)'
  844. // end::builder_default_methods[]
  845. '''
  846. }
  847. void testBuilderInitializer() {
  848. assertScript '''
  849. // tag::builder_initializer[]
  850. import groovy.transform.builder.*
  851. import groovy.transform.*
  852. @ToString
  853. @Builder(builderStrategy=InitializerStrategy)
  854. class Person {
  855. String firstName
  856. String lastName
  857. int age
  858. }
  859. // end::builder_initializer[]
  860. // tag::builder_initializer_usage[]
  861. @CompileStatic
  862. def firstLastAge() {
  863. assert new Person(Person.createInitializer().firstName("John").lastName("Smith").age(21)).toString() == 'Person(John, Smith, 21)'
  864. }
  865. firstLastAge()
  866. // end::builder_initializer_usage[]
  867. '''
  868. assertScript '''
  869. // tag::builder_initializer_immutable[]
  870. import groovy.transform.builder.*
  871. import groovy.transform.*
  872. @Builder(builderStrategy=InitializerStrategy)
  873. @Immutable
  874. class Person {
  875. String first
  876. String last
  877. int born
  878. }
  879. @CompileStatic
  880. def createFirstLastBorn() {
  881. def p = new Person(Person.createInitializer().first('Johnny').last('Depp').born(1963))
  882. assert "$p.first $p.last $p.born" == 'Johnny Depp 1963'
  883. }
  884. createFirstLastBorn()
  885. // end::builder_initializer_immutable[]
  886. '''
  887. }
  888. }