diff --git a/build.gradle b/build.gradle index 0bf152c..402930d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,8 @@ buildscript { maven { url "https://repo.grails.org/grails/core" } } dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:$gormHibernate5Version" + classpath "org.grails:grails-gradle-plugin:$grailsGradlePluginVersion" + classpath "org.grails.plugins:hibernate5:$gormHibernate5Version" classpath "io.github.gradle-nexus:publish-plugin:1.0.0" } } @@ -22,36 +22,35 @@ repositories { maven { url "https://repo.grails.org/grails/core" } } -dependencyManagement { - imports { - mavenBom "org.grails:grails-bom:$grailsVersion" - } - applyMavenExclusions false -} - dependencies { - provided 'org.springframework.boot:spring-boot-starter-logging' - provided "org.springframework.boot:spring-boot-starter-actuator" - provided "org.springframework.boot:spring-boot-autoconfigure" - provided "org.springframework.boot:spring-boot-starter-tomcat" - - provided "org.grails:grails-web-boot" - provided "org.grails.plugins:hibernate5" - compile "org.hibernate:hibernate-core:$hibernateVersion" - compile "org.grails:grails-logging" - compile "org.grails:grails-plugin-rest" - compile "org.grails:grails-plugin-databinding" - compile "org.grails:grails-plugin-i18n" - compile "org.grails:grails-plugin-services" - compile "org.grails:grails-plugin-url-mappings" - compile "org.grails:grails-plugin-interceptors" - compile "org.grails.plugins:async" + implementation "org.grails:grails-core" + + implementation "org.springframework.boot:spring-boot-starter-logging" + implementation "org.springframework.boot:spring-boot-starter-actuator" + implementation "org.springframework.boot:spring-boot-starter-validation" + implementation "org.springframework.boot:spring-boot-autoconfigure" + implementation "org.springframework.boot:spring-boot-starter-tomcat" + + implementation "org.grails:grails-web-boot" + implementation "org.grails.plugins:hibernate5" + implementation "org.hibernate:hibernate-core" + implementation "org.grails:grails-logging" + implementation "org.grails:grails-plugin-rest" + implementation "org.grails:grails-plugin-databinding" + implementation "org.grails:grails-plugin-i18n" + implementation "org.grails:grails-plugin-services" + implementation "org.grails:grails-plugin-url-mappings" + implementation "org.grails:grails-plugin-interceptors" + implementation "org.grails:grails-datastore-gorm-hibernate5:$gormHibernate5Version" + implementation "org.grails.plugins:cache" + implementation "org.grails.plugins:async" profile "org.grails.profiles:web-plugin" - runtime "com.h2database:h2" - runtime "org.apache.tomcat:tomcat-jdbc" - testCompile "org.grails:grails-gorm-testing-support" - testCompile "org.grails.plugins:geb" - testCompile "org.grails:grails-web-testing-support" + runtimeOnly "com.h2database:h2" + runtimeOnly "org.apache.tomcat:tomcat-jdbc" + compileOnly "io.micronaut:micronaut-inject-groovy" + testImplementation "io.micronaut:micronaut-inject-groovy" + testImplementation "org.grails:grails-gorm-testing-support" + testImplementation "org.grails:grails-web-testing-support" console "org.grails:grails-console" } @@ -179,3 +178,11 @@ task snapshotVersion { } } } + +tasks.withType(Test) { + useJUnitPlatform() + testLogging { + events = ["passed", "failed", "skipped"] + showStandardStreams = false + } +} diff --git a/gradle.properties b/gradle.properties index d8f943f..0d67a49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,9 @@ -version=4.0.0-SNAPSHOT -grailsVersion=4.0.11 -gorm.version=7.0.8.RELEASE -gormHibernate5Version=7.0.5 -hibernateVersion=5.4.18.Final +version=5.0.0-SNAPSHOT +grailsVersion=5.3.5 +gorm.version=7.3.4 +gormHibernate5Version=7.3.1 +grailsGradlePluginVersion=5.3.1 +groovyVersion=3.0.11 org.gradle.daemon=true org.gradle.parallel=true org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 542400b..d2d5d93 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Nov 27 23:09:32 CET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml index c6ecffe..61b5bf3 100644 --- a/grails-app/conf/application.yml +++ b/grails-app/conf/application.yml @@ -81,15 +81,15 @@ environments: development: dataSource: dbCreate: create-drop - url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + url: jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE test: dataSource: dbCreate: update - url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + url: jdbc:h2:mem:testDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE production: dataSource: dbCreate: update - url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + url: jdbc:h2:prodDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE properties: jmxEnabled: true initialSize: 5 diff --git a/grails-app/conf/logback.groovy b/grails-app/conf/logback.groovy deleted file mode 100644 index 5b2d1e3..0000000 --- a/grails-app/conf/logback.groovy +++ /dev/null @@ -1,28 +0,0 @@ -import grails.util.BuildSettings -import grails.util.Environment - - -// See http://logback.qos.ch/manual/groovy.html for details on configuration -appender('STDOUT', ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } -} - -root(ERROR, ['STDOUT']) - -if(Environment.current == Environment.DEVELOPMENT) { - def targetDir = BuildSettings.TARGET_DIR - if(targetDir) { - - appender("FULL_STACKTRACE", FileAppender) { - - file = "${targetDir}/stacktrace.log" - append = true - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } - } - logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false ) - } -} diff --git a/grails-app/conf/logback.xml b/grails-app/conf/logback.xml new file mode 100644 index 0000000..a10cfbe --- /dev/null +++ b/grails-app/conf/logback.xml @@ -0,0 +1,20 @@ + + + + + + + + + UTF-8 + %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex + + + + + + + + + + diff --git a/grails-app/init/grails/plugins/taggable/Application.groovy b/grails-app/init/grails/plugins/taggable/Application.groovy index 43f860d..09408b0 100644 --- a/grails-app/init/grails/plugins/taggable/Application.groovy +++ b/grails-app/init/grails/plugins/taggable/Application.groovy @@ -1,8 +1,11 @@ package grails.plugins.taggable + import grails.boot.GrailsApp import grails.boot.config.GrailsAutoConfiguration +import grails.plugins.metadata.PluginSource +@PluginSource class Application extends GrailsAutoConfiguration { static void main(String[] args) { GrailsApp.run(Application, args) diff --git a/grails-app/taglib/grails/plugins/taggable/TagsTagLib.groovy b/grails-app/taglib/grails/plugins/taggable/TagsTagLib.groovy index 8f9b41f..6b2605c 100644 --- a/grails-app/taglib/grails/plugins/taggable/TagsTagLib.groovy +++ b/grails-app/taglib/grails/plugins/taggable/TagsTagLib.groovy @@ -20,7 +20,7 @@ class TagsTagLib { throwTagError("Required attribute [tags] must be a map of tag names to tag counts") } - def classes = grailsApplication.config.grails.taggable.css.classes ?: defaultCssClasses + def classes = grailsApplication.config.getProperty("grails.taggable.css.classes", ArrayList, defaultCssClasses) // The named arguments for the 'link' GSP tag used to display each tag. def idProperty = attrs?.idProperty ?: "id" diff --git a/src/integration-test/groovy/grails/plugins/taggable/TaggableSpec.groovy b/src/integration-test/groovy/grails/plugins/taggable/TaggableSpec.groovy new file mode 100644 index 0000000..7f6d737 --- /dev/null +++ b/src/integration-test/groovy/grails/plugins/taggable/TaggableSpec.groovy @@ -0,0 +1,298 @@ +package grails.plugins.taggable + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration +import spock.lang.Specification + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +@Integration +@Rollback +class TaggableSpec extends Specification { + + def setup() { + Tag.preserveCaseForTesting = false + } + + void testAddTagMethodCaseInsensitive() { + given: + def td = new TestDomain(name: "foo") + td.save() + + when: + td.addTag("Groovy") + .addTag("grails") + and: + def links = TagLink.findAllWhere(tagRef: td.id, type: 'testDomain') + + then: + assertEquals 2, links.size() + assertEquals(['groovy', 'grails'], links.tag.name) + } + + void testAddTagMethodCasePreserving() { + given: + Tag.preserveCaseForTesting = true + + def td = new TestDomain(name:"foo") + td.save() + + when: + td.addTag("Groovy") + .addTag("grails") + + def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + then: + assertEquals 2, links.size() + assertEquals( ['Groovy', 'grails'], links.tag.name ) + + when: + // adding a second, even if preserving case in DB it should still not add it as already has such a tag + td.addTag("groovy") + and: + links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + + then: + assertEquals 3, links.size() + assertEquals( ['Groovy', 'grails', 'groovy'], links.tag.name ) + } + + void testAddTagsMethod() { + given: + def td = new TestDomain(name:"foo") + td.save() + + when: + td.addTags(["groovy","grails"]) + and: + def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + + then: + assertEquals 2, links.size() + assertEquals( ['groovy', 'grails'], links.tag.name ) + } + + void testRemoveTagMethod() { + given: + def td = new TestDomain(name: "foo") + td.save() + + when: + td.addTag("groovy") + .addTag("grails") + and: + def links = TagLink.findAllWhere(tagRef: td.id, type: 'testDomain') + + then: + assertEquals 2, links.size() + assertEquals(['groovy', 'grails'], links.tag.name) + + when: + td.removeTag("groovy") + and: + links = TagLink.findAllWhere(tagRef: td.id, type: 'testDomain') + + then: + assertEquals 1, links.size() + assertEquals(['grails'], links.tag.name) + } + + void testGetTagsMethod() { + given: + def td = new TestDomain(name:"foo") + td.save() + + when: + td.addTag("groovy") + .addTag("grails") + td.save(flush:true) + + and: + TestDomain.withSession { session -> session.clear() } + td = TestDomain.findByName("foo") + + then: + assertEquals( ['groovy', 'grails'], td.tags ) + } + + void testSetTagsMethod() { + given: + def td = new TestDomain(name:"foo") + td.save() + + when: + td.tags = ["groovy", null, "grails", ''] + and: + def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + + then: + assertEquals 2, links.size() + assertEquals( ['groovy', 'grails'], links.tag.name ) + assertEquals( ['groovy', 'grails'], td.tags ) + + when: + td.tags = ["foo", "bar"] + and: + links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + + then: + assertEquals 2, links.size() + assertEquals( ['foo', 'bar'].sort(true), links.tag.name.sort(true) ) + assertEquals( ['foo', 'bar'].sort(true), td.tags.sort(true) ) + + when: + td.tags = [] + and: + links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') + + then: + assertEquals 0, links.size() + assertEquals( [], links.tag.name ) + assertEquals( [], td.tags ) + } + + void testFindAllByTag() { + given: + new TestDomain(name:"foo") + .save() + .addTag("groovy") + .addTag("grails") + .addTag("griffon") + new TestDomain(name:"bar") + .save() + .addTag("groovy") + .addTag("grails") + + when: + def results = TestDomain.findAllByTag("groovy") + + then: + assertEquals 2, results.size() + assertTrue results[0] instanceof TestDomain + + assertEquals 2, TestDomain.findAllByTag("groovy").size() + assertEquals 2, TestDomain.findAllByTag("grails").size() + assertEquals 1, TestDomain.findAllByTag("griffon").size() + assertEquals 0, TestDomain.findAllByTag("nothing").size() + assertEquals 0, TestDomain.findAllByTag(null).size() + + } + + void testFindAllByTagPolymorphic() { + given: + new TestDomain(name:"foo") + .save() + .addTag("groovy") + .addTag("grails") + .addTag("griffon") + new TestDescendent(name:"bar", other:'bla') + .save() + .addTag("groovy") + .addTag("grails") + .addTag("gradle") + + when: + def results = TestDomain.findAllByTag("groovy") + + then: + assertEquals 2, results.size() + assertTrue results[0] instanceof TestDomain + + assertEquals 2, TestDomain.findAllByTag("groovy").size() + assertEquals 1, TestDescendent.findAllByTag("groovy").size() + + assertEquals 2, TestDomain.findAllByTag("grails").size() + assertEquals 1, TestDescendent.findAllByTag("grails").size() + + assertEquals 1, TestDomain.findAllByTag("gradle").size() + assertEquals 1, TestDescendent.findAllByTag("gradle").size() + + assertEquals 1, TestDomain.findAllByTag("griffon").size() + assertEquals 0, TestDomain.findAllByTag("nothing").size() + assertEquals 0, TestDomain.findAllByTag(null).size() + + } + + void testCountByTag() { + given: + new TestDomain(name:"foo") + .save() + .addTag("groovy") + .addTag("grails") + .addTag("griffon") + new TestDomain(name:"bar") + .save() + .addTag("groovy") + .addTag("grails") + new TestDescendent(name:"bla", other:'zzzz') + .save() + .addTag("groovy") + .addTag("grails") + .addTag("gradle") + + expect: + assertEquals 3, TestDomain.countByTag("groovy") + assertEquals 1, TestDescendent.countByTag("groovy") + + assertEquals 1, TestDomain.countByTag("griffon") + assertEquals 0, TestDescendent.countByTag("griffon") + + assertEquals 1, TestDomain.countByTag("gradle") + assertEquals 1, TestDescendent.countByTag("gradle") + + assertEquals 0, TestDomain.countByTag("rubbish") + assertEquals 0, TestDomain.countByTag(null) + + } + + void testAllTags() { + given: + new TestDomain(name:"foo") + .save() + .addTag("groovy") + .addTag("grails") + .addTag("griffon") + new TestDomain(name:"bar") + .save() + .addTag("groovy") + .addTag("grails") + new TestDescendent(name:"bla", other:'zzzz') + .save() + .addTag("groovy") + .addTag("grails") + .addTag("gradle") + + expect: + assertEquals( ['gradle','grails','griffon','groovy'].sort(true), TestDomain.allTags.sort(true) ) + assertEquals 4, TestDomain.totalTags + + assertEquals( ['gradle','grails','groovy'].sort(true), TestDescendent.allTags.sort(true) ) + assertEquals 3, TestDescendent.totalTags + } + + void testParseTags() { + given: + def td = new TestDomain(name:"foo") + .save() + + when: + td.parseTags("groovy,grails,griffon") + + then: + assertEquals( ['grails','griffon','groovy'], TestDomain.allTags ) + } + + void testParseTagsWithDelimiter() { + given: + def td = new TestDomain(name:"foo") + .save() + + when: + td.parseTags("groovy grails griffon", " ") + + then: + assertEquals( ['grails','griffon','groovy'], TestDomain.allTags ) + + } +} diff --git a/src/integration-test/groovy/grails/plugins/taggable/TaggableTests.groovy b/src/integration-test/groovy/grails/plugins/taggable/TaggableTests.groovy deleted file mode 100644 index 29f70f5..0000000 --- a/src/integration-test/groovy/grails/plugins/taggable/TaggableTests.groovy +++ /dev/null @@ -1,276 +0,0 @@ -package grails.plugins.taggable - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.junit.Before -import org.junit.Test - -import static org.junit.Assert.assertEquals -import static org.junit.Assert.assertTrue - -@Integration -@Rollback -class TaggableTests { - @Before - void resetConfig() { - Tag.preserveCaseForTesting = false - } - - @Test - void testAddTagMethodCaseInsensitive() { - def td = new TestDomain(name:"foo") - td.save() - - td.addTag("Groovy") - .addTag("grails") - - def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['groovy', 'grails'], links.tag.name ) - } - - @Test - void testAddTagMethodCasePreserving() { - Tag.preserveCaseForTesting = true - - def td = new TestDomain(name:"foo") - td.save() - - td.addTag("Groovy") - .addTag("grails") - - def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['Groovy', 'grails'], links.tag.name ) - - // adding a second, even if preserving case in DB it should still not add it as already has such a tag - td.addTag("groovy") - - links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 3, links.size() - assertEquals( ['Groovy', 'grails', 'groovy'], links.tag.name ) - } - - @Test - void testAddTagsMethod() { - def td = new TestDomain(name:"foo") - td.save() - - td.addTags(["groovy","grails"]) - - def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['groovy', 'grails'], links.tag.name ) - } - - @Test - void testRemoveTagMethod() { - def td = new TestDomain(name:"foo") - td.save() - - td.addTag("groovy") - .addTag("grails") - - def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['groovy', 'grails'], links.tag.name ) - - td.removeTag("groovy") - - links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - assertEquals 1, links.size() - assertEquals( ['grails'], links.tag.name ) - - } - - @Test - void testGetTagsMethod() { - - def td = new TestDomain(name:"foo") - td.save() - - td.addTag("groovy") - .addTag("grails") - - td.save(flush:true) - - TestDomain.withSession { session -> session.clear() } - - td = TestDomain.findByName("foo") - - assertEquals( ['groovy', 'grails'], td.tags ) - } - - @Test - void testSetTagsMethod() { - def td = new TestDomain(name:"foo") - td.save() - - td.tags = ["groovy", null, "grails", ''] - - def links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['groovy', 'grails'], links.tag.name ) - assertEquals( ['groovy', 'grails'], td.tags ) - - td.tags = ["foo", "bar"] - - links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - - assertEquals 2, links.size() - assertEquals( ['foo', 'bar'].sort(true), links.tag.name.sort(true) ) - assertEquals( ['foo', 'bar'].sort(true), td.tags.sort(true) ) - - td.tags = [] - - links = TagLink.findAllWhere(tagRef:td.id, type:'testDomain') - assertEquals 0, links.size() - assertEquals( [], links.tag.name ) - assertEquals( [], td.tags ) - } - - @Test - void testFindAllByTag() { - new TestDomain(name:"foo") - .save() - .addTag("groovy") - .addTag("grails") - .addTag("griffon") - new TestDomain(name:"bar") - .save() - .addTag("groovy") - .addTag("grails") - - - def results = TestDomain.findAllByTag("groovy") - - assertEquals 2, results.size() - assertTrue results[0] instanceof TestDomain - - assertEquals 2, TestDomain.findAllByTag("groovy").size() - assertEquals 2, TestDomain.findAllByTag("grails").size() - assertEquals 1, TestDomain.findAllByTag("griffon").size() - assertEquals 0, TestDomain.findAllByTag("nothing").size() - assertEquals 0, TestDomain.findAllByTag(null).size() - - } - @Test - void testFindAllByTagPolymorphic() { - new TestDomain(name:"foo") - .save() - .addTag("groovy") - .addTag("grails") - .addTag("griffon") - new TestDescendent(name:"bar", other:'bla') - .save() - .addTag("groovy") - .addTag("grails") - .addTag("gradle") - - - def results = TestDomain.findAllByTag("groovy") - - assertEquals 2, results.size() - assertTrue results[0] instanceof TestDomain - - assertEquals 2, TestDomain.findAllByTag("groovy").size() - assertEquals 1, TestDescendent.findAllByTag("groovy").size() - - assertEquals 2, TestDomain.findAllByTag("grails").size() - assertEquals 1, TestDescendent.findAllByTag("grails").size() - - assertEquals 1, TestDomain.findAllByTag("gradle").size() - assertEquals 1, TestDescendent.findAllByTag("gradle").size() - - assertEquals 1, TestDomain.findAllByTag("griffon").size() - assertEquals 0, TestDomain.findAllByTag("nothing").size() - assertEquals 0, TestDomain.findAllByTag(null).size() - - } - - @Test - void testCountByTag() { - - new TestDomain(name:"foo") - .save() - .addTag("groovy") - .addTag("grails") - .addTag("griffon") - new TestDomain(name:"bar") - .save() - .addTag("groovy") - .addTag("grails") - new TestDescendent(name:"bla", other:'zzzz') - .save() - .addTag("groovy") - .addTag("grails") - .addTag("gradle") - - - assertEquals 3, TestDomain.countByTag("groovy") - assertEquals 1, TestDescendent.countByTag("groovy") - - assertEquals 1, TestDomain.countByTag("griffon") - assertEquals 0, TestDescendent.countByTag("griffon") - - assertEquals 1, TestDomain.countByTag("gradle") - assertEquals 1, TestDescendent.countByTag("gradle") - - assertEquals 0, TestDomain.countByTag("rubbish") - assertEquals 0, TestDomain.countByTag(null) - - } - - @Test - void testAllTags() { - new TestDomain(name:"foo") - .save() - .addTag("groovy") - .addTag("grails") - .addTag("griffon") - new TestDomain(name:"bar") - .save() - .addTag("groovy") - .addTag("grails") - new TestDescendent(name:"bla", other:'zzzz') - .save() - .addTag("groovy") - .addTag("grails") - .addTag("gradle") - - assertEquals( ['gradle','grails','griffon','groovy'].sort(true), TestDomain.allTags.sort(true) ) - assertEquals 4, TestDomain.totalTags - - assertEquals( ['gradle','grails','groovy'].sort(true), TestDescendent.allTags.sort(true) ) - assertEquals 3, TestDescendent.totalTags - } - - @Test - void testParseTags() { - def td = new TestDomain(name:"foo") - .save() - - td.parseTags("groovy,grails,griffon") - - assertEquals( ['grails','griffon','groovy'], TestDomain.allTags ) - } - - @Test - void testParseTagsWithDelimiter() { - def td = new TestDomain(name:"foo") - .save() - - td.parseTags("groovy grails griffon", " ") - - assertEquals( ['grails','griffon','groovy'], TestDomain.allTags ) - - } - - -}