blob: c96841ea8c591ad5d96a72e172c0d71d0bc82ec4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 groovy.util
import groovy.test.GroovyTestCase
/**
* Tests for the ConfigSlurper class
*
* @since 0.6
*/
class ConfigSlurperTest extends GroovyTestCase {
void testConsecutiveSlurperValues() {
def config = new ConfigSlurper().parse('''
grails.views.default.codec="none"
grails {
mail {
host = "smtp.foo.com"
port = 25
username = "foo"
password = "bar"
}
}
''')
assertEquals "none", config.grails.views.default.codec
assertEquals "smtp.foo.com", config.grails.mail.host
}
void testConfigSlurperNestedValues() {
def config = new ConfigSlurper().parse('''
foo {
bar {
password="value"
}
fruit="orange"
}
''')
assertEquals "value", config.foo.bar.password
assertEquals "orange", config.foo.fruit
config = new ConfigSlurper().parse('''
foo {
bar.password="value"
fruit="orange"
}
''')
assertEquals "value", config.foo.bar.password
assertEquals "orange", config.foo.fruit
}
void testConfigBinding() {
def slurper = new ConfigSlurper()
slurper.binding = [foo: "bar"]
def config = slurper.parse('''
test=foo + 1
''')
assertEquals "bar1", config.test
}
void testEnvironmentProperties2() {
def config = new ConfigSlurper("production").parse('''
dataSource {
pooling = false
driverClassName = "org.hsqldb.jdbc.JDBCDriver"
username = "sa"
password = ""
}
environments {
development {
dataSource {
dbCreate = "create-drop"
url = "jdbc:hsqldb:mem:devDB"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDB"
}
}
production {
dataSource {
password = "secret"
dbCreate = "update"
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
}
}
}''')
assertEquals false, config.dataSource.pooling
assertEquals "org.hsqldb.jdbc.JDBCDriver", config.dataSource.driverClassName
assertEquals "sa", config.dataSource.username
assertEquals "secret", config.dataSource.password
assertEquals "update", config.dataSource.dbCreate
assertEquals "jdbc:hsqldb:file:prodDb;shutdown=true", config.dataSource.url
}
void testParseProperties() {
Properties props = new Properties()
props['foo'] = 'bar'
props['log4j.appender.NULL'] = 'org.apache.log4j.varia.NullAppender'
props['log4j.rootLogger'] = 'error, NULL'
props['log4j.logger.org.codehaus.groovy.grails.plugins'] = 'info,NULL'
props['log4j.additivity.org.codehaus.groovy.grails.plugins'] = 'false'
props['log4j.additivity.org.springframework'] = 'false'
props['log4j.logger.grails.spring'] = 'info,NULL'
props['log4j.appender.NULL.layout'] = 'org.apache.log4j.PatternLayout'
def config = new ConfigSlurper().parse(props)
assertEquals "org.apache.log4j.PatternLayout", config.log4j.appender.'NULL.layout' // tests overlapping properties
assertEquals "org.apache.log4j.varia.NullAppender", config.log4j.appender.NULL // tests overlapping properties
assertEquals 'error, NULL', config.log4j.rootLogger
assertEquals 'info,NULL', config.log4j.logger.org.codehaus.groovy.grails.plugins
assertEquals 'false', config.log4j.additivity.org.springframework
assertEquals 'bar', config.foo
}
void testSimpleProperties() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
smtp.server.url = "localhost"
smtp.username = "fred"
smtp.dummy = null
''')
assert config
assertEquals "localhost", config.smtp.server.url
assertEquals "fred", config.smtp.username
assertNull config.smtp.dummy
}
void testScopedProperties() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
smtp {
mail.host = 'smtp.myisp.com'
mail.auth.user = 'server'
}
resources.URL = "http://localhost:80/resources"
''')
assert config
assertEquals "smtp.myisp.com", config.smtp.mail.host
assertEquals "server", config.smtp.mail.auth.user
assertEquals "http://localhost:80/resources", config.resources.URL
}
void testScopedPropertiesWithNesting() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
smtp {
mail {
host = 'smtp.myisp.com'
auth.user = 'server'
}
}
resources.URL = "http://localhost:80/resources"
''')
assert config
assert "smtp.myisp.com" == config.smtp.mail.host
assertEquals "server", config.smtp.mail.auth.user
assertEquals "http://localhost:80/resources", config.resources.URL
}
void testScopedVariableReusage() {
def conf = '''
a0 = "Goofy"
a1 = "$a0"
a2."$a0" = "Mickey Mouse and " + "$a0"
group1 { a0 = "Donald Duck" }
group2 {
a0 = a0
a1 = "$group1.a0"
group3 {
a0 = "inner$a0"
group4 {
a0 = "inner$a0"
a1 = a1
a3 = "Dagobert Duck"
}
}
a3 = a3
}
a3 = "$group1.a0"
'''
def config = new ConfigSlurper().parse(conf)
assert config.group1.a0 == "Donald Duck"
assert config.group2.a0 == "Goofy"
assert config.group2.group3.a0 == "innerGoofy"
assert config.group2.group3.group4.a0 == "innerinnerGoofy"
assert config.group2.group3.group4.a1 == "Donald Duck"
assert config.group2.group3.group4.a3 == "Dagobert Duck"
assert config.group2.a3 == [:]
assert config.a3 == "Donald Duck"
}
void testLog4jConfiguration() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
log4j {
appender {
stdout("org.apache.log4j.ConsoleAppender") {
layout="org.apache.log4j.PatternLayout"
}
}
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity {
org.codehaus.groovy.grails=false
org.springframework=false
}
}
''')
assert config
//println config
assertEquals "org.apache.log4j.ConsoleAppender", config.log4j.appender.stdout
assertEquals "org.apache.log4j.PatternLayout", config.log4j.appender."stdout.layout"
assertEquals "error,stdout", config.log4j.rootLogger
assertEquals "info,stdout", config.log4j.logger.org.codehaus.groovy.grails
assertEquals false, config.log4j.additivity.org.codehaus.groovy.grails
}
void testEnvironmentSpecificConfig() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
log4j {
appender {
stdout("org.apache.log4j.ConsoleAppender") {
layout="org.apache.log4j.PatternLayout"
}
}
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity {
org.codehaus.groovy.grails=false
org.springframework=false
}
}
environments {
development {
log4j.logger.org.codehaus.groovy.grails="debug,stdout"
}
}
''')
assert config
assertEquals "org.apache.log4j.ConsoleAppender", config.log4j.appender.stdout
assertEquals "org.apache.log4j.PatternLayout", config.log4j.appender."stdout.layout"
assertEquals "error,stdout", config.log4j.rootLogger
assertEquals "info,stdout", config.log4j.logger.org.codehaus.groovy.grails
assertEquals false, config.log4j.additivity.org.codehaus.groovy.grails
slurper.setEnvironment("development")
config = slurper.parse('''
log4j {
appender {
stdout("org.apache.log4j.ConsoleAppender") {
layout="org.apache.log4j.PatternLayout"
}
}
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity {
org.codehaus.groovy.grails=false
org.springframework=false
}
}
environments {
development {
log4j.logger.org.codehaus.groovy.grails="debug,stdout"
log4j.appender.layout="MyLayout"
}
production {
log4j.appender.stdout="MyRobustFileAppender"
}
}
''')
assert config
assertEquals "org.apache.log4j.ConsoleAppender", config.log4j.appender.stdout
assertEquals "MyLayout", config.log4j.appender.layout
assertEquals "error,stdout", config.log4j.rootLogger
assertEquals "debug,stdout", config.log4j.logger.org.codehaus.groovy.grails
assertEquals false, config.log4j.additivity.org.codehaus.groovy.grails
}
void testFlattenConfig() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
log4j {
appender {
stdout("org.apache.log4j.ConsoleAppender") {
layout="org.apache.log4j.PatternLayout"
}
}
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity {
org.codehaus.groovy.grails=false
org.springframework=false
}
}
''')
config = config.flatten()
assertEquals "org.apache.log4j.ConsoleAppender", config."log4j.appender.stdout"
assertEquals "org.apache.log4j.PatternLayout", config."log4j.appender.stdout.layout"
assertEquals "error,stdout", config."log4j.rootLogger"
assertEquals "info,stdout", config."log4j.logger.org.codehaus.groovy.grails"
assertEquals false, config."log4j.additivity.org.codehaus.groovy.grails"
}
void testToProperties() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
smtp.dummy = null
log4j {
appender {
stdout("org.apache.log4j.ConsoleAppender") {
layout="org.apache.log4j.PatternLayout"
}
}
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity {
org.codehaus.groovy.grails=false
org.springframework=false
}
}
''')
def props = config.toProperties()
assert props
assertEquals "org.apache.log4j.ConsoleAppender", props."log4j.appender.stdout"
assertEquals "org.apache.log4j.PatternLayout", props."log4j.appender.stdout.layout"
assertEquals "error,stdout", props."log4j.rootLogger"
assertEquals "info,stdout", props."log4j.logger.org.codehaus.groovy.grails"
assertEquals "false", props."log4j.additivity.org.codehaus.groovy.grails"
assertNull props.'smtp.dummy'
props = config.log4j.toProperties("log4j")
assertEquals "org.apache.log4j.ConsoleAppender", props."log4j.appender.stdout"
assertEquals "org.apache.log4j.PatternLayout", props."log4j.appender.stdout.layout"
assertEquals "error,stdout", props."log4j.rootLogger"
assertEquals "info,stdout", props."log4j.logger.org.codehaus.groovy.grails"
assertEquals "false", props."log4j.additivity.org.codehaus.groovy.grails"
assertFalse props.containsKey('smtp.dummy')
}
void testConfigTokensAsStrings() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
log4j {
appender.stdout = "org.apache.log4j.ConsoleAppender"
appender."stdout.layout"="org.apache.log4j.PatternLayout"
rootLogger="error,stdout"
}
''')
assert config
assertEquals "org.apache.log4j.ConsoleAppender", config.log4j.appender.stdout
assertEquals "org.apache.log4j.PatternLayout", config.log4j.appender."stdout.layout"
assertEquals "error,stdout", config.log4j.rootLogger
}
void testConfigInterReferencing() {
def slurper = new ConfigSlurper()
def config = slurper.parse('''
var.one=5
var.two=var.one*2
''')
assertEquals 5, config.var.one
assertEquals 10, config.var.two
}
void testSerializeConfig() {
def text = '''
log4j {
appender.stdout="org.apache.log4j.ConsoleAppender"
appender.'stdout.layout'="org.apache.log4j.PatternLayout"
rootLogger="error,stdout"
logger {
org.codehaus.groovy.grails="info,stdout"
org.springframework="info,stdout"
}
additivity.'default' = true
additivity.org.codehaus.groovy.grails=false
additivity.org.springframework=false
}'''
def slurper = new ConfigSlurper()
def config = slurper.parse(text)
assert config
def sw = new StringWriter()
config.writeTo(sw)
def newText = sw.toString()
//println newText
config = slurper.parse(newText)
assertEquals "org.apache.log4j.ConsoleAppender", config.log4j.appender.stdout
assertEquals "org.apache.log4j.PatternLayout", config.log4j.appender."stdout.layout"
assertEquals "error,stdout", config.log4j.rootLogger
assertEquals "info,stdout", config.log4j.logger.org.codehaus.groovy.grails
assertEquals false, config.log4j.additivity.org.codehaus.groovy.grails
}
void testCloneConfig() {
ConfigObject original = new ConfigSlurper().parse('foo { bar = "barValue" }')
ConfigObject clone = original.clone()
assert clone.foo.bar == "barValue"
}
void testNotProperlyNestedPropertiesArePreserved() throws IOException {
Properties props = new Properties()
props.load(ConfigSlurperTest.class.getResourceAsStream("system.properties"))
assertEquals("false", props.get("catalog.prov"))
assertEquals("sa", props.get("catalog.prov.db.user"))
// now round-trip via ConfigSlurper
ConfigSlurper configSlurper = new ConfigSlurper()
ConfigObject newConfig = configSlurper.parse(props)
props = newConfig.toProperties()
assertEquals("false", props.get("catalog.prov"))
assertEquals("sa", props.get("catalog.prov.db.user"))
}
void testSameElementNestingWithoutDuplication() {
def cfg = """
a { b { a { foo = 1 } } }
a.foo = 2
a { b { a { bar = 3 } } }
"""
ConfigObject c = new ConfigSlurper().parse(cfg)
assert c.a.b.a.foo == 1
assert c.a != c.a.b.a
assert c.a.foo == 2
assert c.a.b.a.bar == 3
}
/**
* Test for GROOVY-3186:
* ConfigSlurper only allows a single block for any given name
*/
void testTwoSameBlocks() {
def config = new ConfigSlurper().parse("""
topNode {
one = "1"
}
topNode {
two = "2"
}
log4j {
logger {
foo.bar = "debug"
}
}
log4j {
logger.extraLogger = "info"
}
""")
assert config.topNode.one == "1"
assert config.topNode.two == "2"
assert config.log4j.logger.foo.bar == "debug"
assert config.log4j.logger.extraLogger == "info"
}
/**
* Test for GROOVY-5370: ConfigSlurper - multiple environment blocks broken
*/
void testMultipleToplevelEnvironmentBlocksForSameEnvironment() {
def config = new ConfigSlurper('development').parse("""
environments {
development {
a = 1
}
}
environments {
development {
b = 2
}
}
""")
assert config == [a:1, b:2]
}
/**
* Test for GROOVY-5370: ConfigSlurper - multiple environment blocks broken
*/
void testMultipleEnvironmentBlocksOnDifferentLevelsForSameEnvironment() {
def config = new ConfigSlurper('development').parse("""
environments {
development {
a = 1
}
}
blah {
environments {
development {
c = 3
}
}
}
""")
assert config == [a:1, blah:[c: 3]]
}
void testVariableAssignments() {
def conf = '''
griffon.cli.verbose = true
griffon.rt.verbose = true
projects {
custom {
this."griffon.cli.verbose" = false
griffon{rt{verbose = false}}
}
}
'''
def config = new ConfigSlurper().parse(conf)
assert config.griffon.cli.verbose
assert !config.projects.custom.griffon.cli.verbose
assert config.griffon.rt.verbose
assert !config.projects.custom.griffon.rt.verbose
}
void testCustomConditionalBlocks() {
def conf = '''
griffon.cli.verbose = true
projects {
custom {
//griffon{cli{verbose = false}} // OK
//this."griffon.cli.verbose" = false // fails
griffon {
cli.verbose = false
}
}
}
'''
ConfigSlurper slurper = new ConfigSlurper()
slurper.registerConditionalBlock('projects', 'bogus')
def config = slurper.parse(conf)
assert config.griffon.cli.verbose
slurper.registerConditionalBlock('projects', 'custom')
config = slurper.parse(conf)
assert !config.griffon.cli.verbose
}
void testNestedConditionaBlocks() {
def conf = '''
var = 1
projects {
custom {
var = 2
environments {
development {
var = 3
}
local {
var = 4
}
}
}
extension {
var = 7
}
}
environments {
development {
var = 5
}
production {
var = 6
}
}
'''
ConfigSlurper slurper = new ConfigSlurper()
slurper.binding = [slurper:slurper]
def config = slurper.parse(conf)
assert config.var == 1
slurper.registerConditionalBlock('environments', 'production')
config = slurper.parse(conf)
assert config.var == 6
slurper.registerConditionalBlock('environments', 'test')
config = slurper.parse(conf)
assert config.var == 1
slurper.registerConditionalBlock('projects', 'custom')
config = slurper.parse(conf)
assert config.var == 2
slurper.registerConditionalBlock('environments', 'local')
config = slurper.parse(conf)
assert config.var == 4
slurper.registerConditionalBlock('projects', 'bogus')
config = slurper.parse(conf)
assert config.var == 1
}
void testConditionalOverrides() {
def conf = '''
environments {
development {
var1 = 1
var2 = 2
}
production {
var1 = 3
var2 = 4
}
}
var1 = 5
var2 = 6
'''
ConfigSlurper slurper = new ConfigSlurper()
slurper.binding = [slurper:slurper]
def config = slurper.parse(conf)
assert config.var1 == 5
assert config.var2 == 6
slurper.registerConditionalBlock('environments', 'development')
config = slurper.parse(conf)
assert config.var1 == 1
assert config.var2 == 2
}
}