blob: 1550adfae2a99a780295921a507034458d1e88d9 [file] [log] [blame]
package ioc.specs
import java.security.AccessController;
import org.apache.commons.lang3.SystemUtils
import org.apache.tapestry5.ioc.internal.util.ClasspathResource
import org.slf4j.Logger;
import spock.lang.Issue;
import spock.lang.Specification
class ClasspathResourceSpec extends Specification {
static final String RESOURCE_TXT_CONTENT = "content from resource.txt";
static final String FOLDER = "org/apache/tapestry5/ioc/internal/util";
static final String PATH = FOLDER + "/resource.txt";
public static final String SAME_FOLDER_RESOURCE_CONTENT = "content from same-folder resource"
def content(resource) {
resource.toURL().text.trim()
}
def "get URL of resource"() {
def r = new ClasspathResource(PATH)
expect:
content(r) == RESOURCE_TXT_CONTENT
}
def "case-mismatch on file name is detected on case insensitive OS"() {
if (!SystemUtils.IS_OS_WINDOWS)
return
def r = new ClasspathResource("$FOLDER/Resource.Txt")
when:
r.toURL()
then:
IllegalStateException e = thrown()
e.message == "Resource classpath:org/apache/tapestry5/ioc/internal/util/Resource.Txt does not match the case of the actual file name, 'resource.txt'."
}
def "expand path from root resource yields same URL as full path"() {
def r = new ClasspathResource("").forFile(PATH)
expect:
content(r) == RESOURCE_TXT_CONTENT
}
def "a leading slash is ignored for the root resource"() {
def r = new ClasspathResource("/").forFile(PATH)
expect:
content(r) == RESOURCE_TXT_CONTENT
}
def "a leading slash is ignored for the path from the root resource"() {
def r = new ClasspathResource("/").forFile("/" + PATH)
expect:
content(r) == RESOURCE_TXT_CONTENT
}
def "path and file for resource are available"() {
when:
def r = new ClasspathResource(PATH)
then:
r.folder == FOLDER
r.file == "resource.txt"
}
def "access a file in the same folder"() {
when:
def r = new ClasspathResource(PATH)
def n = r.forFile("same-folder.txt")
then:
content(n) == SAME_FOLDER_RESOURCE_CONTENT
}
def "access a file in same folder using using ./ relative path"() {
when:
def r = new ClasspathResource(PATH)
def n = r.forFile("./same-folder.txt")
then:
content(n) == SAME_FOLDER_RESOURCE_CONTENT
}
def "multiple slashes treated as a single slash"() {
when:
def r = new ClasspathResource(PATH)
def n = r.forFile("././/.///same-folder.txt")
then:
content(n) == SAME_FOLDER_RESOURCE_CONTENT
}
def "file in subfolder"() {
when:
def r = new ClasspathResource(PATH)
def n = r.forFile("sub/sub-folder.txt")
then:
content(n) == "content from sub-folder resource"
}
def "reference same resource yields same instance"() {
when:
def r = new ClasspathResource(PATH)
then:
r.forFile("../util/resource.txt").is(r)
}
def "access file in parent folder"() {
def r = new ClasspathResource(PATH)
when:
def n = r.forFile("../parent-folder.txt")
then:
content(n) == "content from parent-folder resource"
}
def "toString() is meaningful"() {
expect:
new ClasspathResource(PATH).toString() == "classpath:$PATH"
}
def "URL for a missing resource is null"() {
when:
def r = new ClasspathResource("$FOLDER/missing-resource.txt")
then:
r.toURL() == null
}
def "localization of a resource"() {
def r = new ClasspathResource(PATH)
when:
def l = r.forLocale(Locale.FRENCH)
then:
content(l) == "french content"
}
def "localization finds closest match"() {
def r = new ClasspathResource(PATH)
when:
def l = r.forLocale(Locale.CANADA_FRENCH)
then:
content(l) == "french content"
}
def "localization to base resource"() {
def r = new ClasspathResource(PATH)
when:
def l = r.forLocale(Locale.JAPANESE)
then:
l.is(r)
}
def "localization of missing resource is null"() {
def r = new ClasspathResource("$FOLDER/missing-resource.txt")
expect:
r.forLocale(Locale.KOREAN) == null
}
def "extending to new extension that matches old extension yields same Resource"() {
def r = new ClasspathResource(PATH)
when:
def n = r.withExtension("txt")
then:
n.is(r)
}
def "extending with a new extension"() {
def r = new ClasspathResource(PATH)
when:
def n = r.withExtension("ext")
then:
content(n) == "ext content"
}
def "a new extension that does not exist is a null URL"() {
def r = new ClasspathResource(PATH)
expect:
r.withExtension("does-not-exist").toURL() == null
}
def "up dir from root folder resolves correctly"() {
def r = new ClasspathResource("root/a-file")
expect:
r.forFile("../foo/bar").toString() == "classpath:foo/bar"
}
@Issue('TAP5-2448')
def "Cannot open a stream for a directory resource within a JAR file"() {
setup:
ClasspathResource r = new ClasspathResource('org/slf4j/spi')
when:
r.openStream()
then:
IOException e = thrown()
e.message.contains 'Cannot open a stream for a resource that references a directory inside a JAR file'
}
@Issue('TAP5-2448')
def "Can open a stream for a file resource within a JAR file"() {
setup:
ClasspathResource r = new ClasspathResource('org/slf4j/helpers/Util.class')
when:
r.openStream()
then:
notThrown(IOException)
}
@Issue('TAP5-2517')
def "Can open a stream for a file resource within a JAR file that has a duplicate on the classpath"() {
setup:
def currentCl = Thread.currentThread().contextClassLoader
def resourcePath = 'META-INF/maven/org.slf4j/slf4j-api/pom.xml'
def resourceURLs = currentCl.findResources resourcePath
def slf4jApiURL = resourceURLs.find{it.toString().contains('.jar!')}
ClassLoader cl = new URLClassLoader(slf4jApiURL as URL[], (ClassLoader) null)
ClasspathResource r = new ClasspathResource(cl, resourcePath)
when:
r.openStream()
then:
notThrown(IOException)
}
}