org.gradle.model.managed.ModelSetIntegrationTest.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.model.managed
import org.gradle.integtests.fixtures.AbstractIntegrationSpec
class ModelSetIntegrationTest extends AbstractIntegrationSpec {
def "provides basic meta-data for set"() {
when:
buildScript '''
@Managed
interface Person {
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
}
}
apply type: Rules
model {
tasks {
create("printPeople") {
doLast {
def people = $.people
println "name: $people.name"
println "display-name: $people.displayName"
println "to-string: ${people.toString()}"
}
}
}
}
'''
then:
succeeds "printPeople"
and:
output.contains "name: people"
output.contains "display-name: ModelSet 'people'"
output.contains "to-string: ModelSet 'people'"
}
def "can view as ModelElement"() {
when:
buildScript '''
@Managed
interface Person {
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
}
@Mutate
void tasks(ModelMap tasks, @Path("people") ModelElement people) {
tasks.create("printPeople") {
doLast {
println "name: $people.name"
println "display-name: $people.displayName"
println "to-string: ${people.toString()}"
}
}
}
}
apply type: Rules
'''
then:
succeeds "printPeople"
and:
output.contains "name: people"
output.contains "display-name: ModelSet 'people'"
output.contains "to-string: ModelSet 'people'"
}
def "rule can create a managed collection of interface backed managed model elements"() {
when:
buildScript '''
@Managed
interface Person {
String getName()
void setName(String string)
}
class Names {
List names = []
}
class Rules extends RuleSource {
@Model
Names names() {
return new Names(names: ["p1", "p2"])
}
@Model
void people(ModelSet people, Names names) {
names.names.each { n ->
people.create { name = n }
}
}
@Mutate void addPeople(ModelSet people) {
people.create { name = "p3" }
people.create { name = "p4" }
}
}
apply type: Rules
model {
people {
create { name = "p0" }
}
tasks {
create("printPeople") {
doLast {
def people = $.people
def names = people*.name.sort().join(", ")
println "names: $names"
}
}
}
}
'''
then:
succeeds "printPeople"
and:
output.contains 'names: p0, p1, p2, p3, p4'
}
def "rule can create a managed collection of abstract class backed managed model elements"() {
when:
buildScript '''
@Managed
abstract class Person {
abstract String getName()
abstract void setName(String string)
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
people.create { name = "p1" }
people.create { name = "p2" }
}
}
apply type: Rules
model {
tasks {
def people = $.people
create("printPeople") {
doLast {
def names = people*.name.sort().join(", ")
println "people: $names"
}
}
}
}
'''
then:
succeeds "printPeople"
and:
output.contains 'people: p1, p2'
}
def "rule can create a set of various supported types"() {
when:
buildScript '''
@Managed
interface Thing extends Named {
void setValue(String value)
String getValue()
}
class Rules extends RuleSource {
@Model
void mapThings(ModelSet> things) {
things.create {
a(Thing) {
value = '1'
}
b(Thing)
}
}
@Model
void setThings(ModelSet> things) {
things.create {
create { value = '1' }
}
}
@Model
void setStrings(ModelSet> strings) {
strings.create {
add 'a'
}
}
}
apply type: Rules
model {
mapThings {
create {
a(Thing)
}
}
setStrings {
create {
add 'b'
}
}
tasks {
create("print") {
doLast {
println "mapThings: " + ($.mapThings as List)*.keySet()
println "setThings: " + ($.setThings as List)
println "setStrings: " + ($.setStrings as List)
}
}
}
}
'''
then:
succeeds "print"
and:
output.contains "mapThings: [[a, b], [a]]"
output.contains "setThings: [[Thing 'setThings.0.0']]"
output.contains "setStrings: [[a], [b]]"
}
def "managed model type has property of collection of managed types"() {
when:
buildScript '''
@Managed
interface Person {
String getName()
void setName(String string)
}
@Managed
interface Group {
String getName()
void setName(String string)
ModelSet getMembers()
}
class Rules extends RuleSource {
@Model
void group(Group group) {
group.name = "Women in computing"
group.members.create { name = "Ada Lovelace" }
group.members.create { name = "Grace Hooper" }
assert group.members.is(group.members)
}
}
apply type: Rules
model {
tasks {
def g = $.group
create("printGroup") {
doLast {
def members = g.members*.name.sort().join(", ")
def name = g.name
println "$name: $members"
}
}
}
}
'''
then:
succeeds "printGroup"
and:
output.contains 'Women in computing: Ada Lovelace, Grace Hooper'
}
def "managed model cannot have a reference to a model set"() {
when:
buildScript '''
@Managed
interface Person {
String getName()
void setName(String string)
}
@Managed
interface Group {
String getName()
void setName(String string)
ModelSet getMembers()
//Invalid setter
void setMembers(ModelSet members)
}
class Rules extends RuleSource {
@Model
void group(Group group, @Path("people") ModelSet people) {
}
}
apply type: Rules
'''
then:
fails "tasks"
and:
failure.assertHasCause "Exception thrown while executing model rule: Rules#group"
failure.assertHasCause """Type Group is not a valid managed type:
- Property 'members' is not valid: it cannot have a setter (ModelSet properties must be read only)"""
}
def "rule method can apply defaults to a managed set"() {
when:
buildScript '''
@Managed
interface Person {
String getName()
void setName(String string)
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
println "initialize"
}
@Defaults void initialPeople(ModelSet people) {
println "apply defaults"
}
@Mutate void customPeople(ModelSet people) {
println "configure"
}
@Finalize void finalPeople(ModelSet people) {
println "finalize"
}
}
apply type: Rules
model {
tasks {
create("printPeople") {
doLast {
def people = $.people
println "people: $people"
}
}
}
}
'''
then:
succeeds "printPeople"
and:
output.contains '''apply defaults
initialize
configure
finalize
'''
}
def "creation and configuration of managed set elements is deferred until required"() {
when:
buildScript '''
@Managed
abstract class Person {
Person() {
println "construct Person"
}
abstract String getName()
abstract void setName(String string)
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
people.create {
println "configure p1"
name = "p1"
}
println "p1 defined"
}
@Mutate void addPeople(ModelSet people) {
people.create {
println "configure p2"
name = "p2"
}
println "p2 defined"
}
}
apply type: Rules
model {
people {
create {
println "configure p3"
name = "p3"
}
println "p3 defined"
}
tasks {
create("printPeople") {
doLast {
def names = $.people*.name.sort().join(", ")
println "people: $names"
}
}
}
}
'''
then:
succeeds "printPeople"
and:
output.contains '''p1 defined
p2 defined
p3 defined
construct Person
configure p1
construct Person
configure p2
construct Person
configure p3
'''
output.contains "people: p1, p2, p3"
}
def "reports failure that occurs in collection item initializer"() {
when:
buildScript '''
@Managed
interface Person {
String getName()
void setName(String string)
}
class Rules extends RuleSource {
@Model
void people(ModelSet people) {
people.create {
throw new RuntimeException("broken")
}
}
@Mutate
void tasks(ModelMap tasks, ModelSet people) { }
}
apply type: Rules
'''
then:
fails "printPeople"
and:
failure.assertHasDescription('A problem occurred configuring root project')
failure.assertHasCause('Exception thrown while executing model rule: Rules#people')
failure.assertHasCause('broken')
}
def "read methods of ModelSet throw exceptions when used in a creation rule"() {
when:
buildScript '''
@Managed
interface Person {
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {
people.size()
}
@Mutate
void addDependencyOnPeople(ModelMap tasks, ModelSet people) {
}
}
apply type: RulePlugin
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: RulePlugin#people(ModelSet)")
failure.assertHasCause("Attempt to read from a write only view of model element 'people' of type 'ModelSet' given to rule RulePlugin#people(ModelSet)")
}
def "read methods of ModelSet throw exceptions when used in a mutation rule"() {
when:
buildScript '''
@Managed
interface Person {
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {
}
@Mutate
void readPeople(ModelSet people) {
people.toList()
}
@Mutate
void addDependencyOnPeople(ModelMap tasks, ModelSet people) {
}
}
apply type: RulePlugin
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: RulePlugin#readPeople(ModelSet)")
failure.assertHasCause("Attempt to read from a write only view of model element 'people' of type 'ModelSet' given to rule RulePlugin#readPeople(ModelSet)")
}
def "mutating a managed set that is an input of a rule is not allowed"() {
when:
buildScript '''
@Managed
interface Person {
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {}
@Mutate
void tryToMutateInputModelSet(ModelMap tasks, ModelSet people) {
people.create {}
}
}
apply type: RulePlugin
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: RulePlugin#tryToMutateInputModelSet(ModelMap, ModelSet)")
failure.assertHasCause("Attempt to modify a read only view of model element 'people' of type 'ModelSet' given to rule RulePlugin#tryToMutateInputModelSet(ModelMap, ModelSet)")
}
def "mutating a managed set that is the subject of a validation rule is not allowed"() {
when:
buildScript '''
@Managed
interface Person {
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {}
@Validate
void check(ModelSet people) {
people.create { }
}
@Mutate
void tryToMutateInputModelSet(ModelMap tasks, ModelSet people) {
}
}
apply type: RulePlugin
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: RulePlugin#check(ModelSet)")
failure.assertHasCause("Attempt to modify a read only view of model element 'people' of type 'ModelSet' given to rule RulePlugin#check(ModelSet)")
}
def "mutating a managed set outside of a creation rule is not allowed"() {
when:
buildScript '''
@Managed
interface Person {
}
class Holder {
static ModelSet people
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {
Holder.people = people
}
@Mutate
void tryToMutateModelSetOutsideOfCreationRule(ModelMap tasks, ModelSet people) {
Holder.people.create {}
}
}
apply type: RulePlugin
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: RulePlugin#tryToMutateModelSetOutsideOfCreationRule(ModelMap, ModelSet)")
failure.assertHasCause("Attempt to modify a closed view of model element 'people' of type 'ModelSet' given to rule RulePlugin#people(ModelSet)")
}
def "mutating managed set which is an input of a DSL rule is not allowed"() {
when:
buildScript '''
@Managed
interface Person {
}
class RulePlugin extends RuleSource {
@Model
void people(ModelSet people) {
}
}
apply type: RulePlugin
model {
tasks {
$.people.create {}
}
}
'''
then:
fails "tasks"
and:
failure.assertHasCause("Exception thrown while executing model rule: tasks { ... } @ build.gradle")
failure.assertHasCause("Attempt to modify a read only view of model element 'people' of type 'ModelSet' given to rule tasks { ... } @ build.gradle")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy