348 lines
10 KiB
Groovy
348 lines
10 KiB
Groovy
|
import groovy.io.FileType
|
||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||
|
import org.gradle.api.tasks.Exec
|
||
|
|
||
|
buildscript {
|
||
|
repositories {
|
||
|
mavenCentral()
|
||
|
jcenter()
|
||
|
}
|
||
|
dependencies {
|
||
|
classpath 'com.eriwen:gradle-js-plugin:1.8.0'
|
||
|
classpath 'com.moowork.gradle:gradle-grunt-plugin:0.2'
|
||
|
}
|
||
|
}
|
||
|
|
||
|
apply plugin: 'js'
|
||
|
apply plugin: 'grunt'
|
||
|
|
||
|
repositories {
|
||
|
mavenCentral()
|
||
|
}
|
||
|
|
||
|
configurations {
|
||
|
rhino
|
||
|
}
|
||
|
|
||
|
dependencies {
|
||
|
rhino 'org.mozilla:rhino:1.7R4'
|
||
|
}
|
||
|
|
||
|
project.ext {
|
||
|
packageProps = new groovy.json.JsonSlurper().parseText(new File("package.json").toURL().text)
|
||
|
failures = 0;
|
||
|
rhinoTestSrc = "out/rhino-test-${packageProps.version}.js"
|
||
|
testSrc = 'test/less'
|
||
|
testOut = 'out/test'
|
||
|
}
|
||
|
|
||
|
task runGruntRhino(type: GruntTask) {
|
||
|
gruntArgs = "rhino"
|
||
|
}
|
||
|
|
||
|
combineJs {
|
||
|
dependsOn runGruntRhino
|
||
|
source = ["dist/less-rhino-${packageProps.version}.js", "test/rhino/test-header.js","dist/lessc-rhino-${packageProps.version}.js"]
|
||
|
dest = file(rhinoTestSrc)
|
||
|
}
|
||
|
|
||
|
task testRhino(type: AllRhinoTests) {
|
||
|
// dependsOn 'testRhinoBase'
|
||
|
dependsOn 'testRhinoBase', 'testRhinoErrors', 'testRhinoLegacy', 'testRhinoStaticUrls', 'testRhinoCompression', 'testRhinoDebugAll', 'testRhinoDebugComments', 'testRhinoDebugMediaquery', 'testRhinoNoJsError', 'testRhinoSourceMap'
|
||
|
}
|
||
|
|
||
|
task testRhinoBase(type: RhinoTest) {
|
||
|
options = [ '--strict-math=true', '--relative-urls' ]
|
||
|
}
|
||
|
|
||
|
task testRhinoDebugAll(type: DebugRhinoTest) {
|
||
|
options = [ '--strict-math=true', '--line-numbers=all' ]
|
||
|
testDir = 'debug' + fs
|
||
|
suffix = "-all"
|
||
|
}
|
||
|
|
||
|
task testRhinoDebugComments(type: DebugRhinoTest) {
|
||
|
options = [ '--strict-math=true', '--line-numbers=comments' ]
|
||
|
testDir = 'debug' + fs
|
||
|
suffix = "-comments"
|
||
|
}
|
||
|
|
||
|
task testRhinoDebugMediaquery(type: DebugRhinoTest) {
|
||
|
options = [ '--strict-math=true', '--line-numbers=mediaquery' ]
|
||
|
testDir = 'debug' + fs
|
||
|
suffix = "-mediaquery"
|
||
|
}
|
||
|
|
||
|
task testRhinoErrors(type: RhinoTest) {
|
||
|
options = [ '--strict-math=true', '--strict-units=true' ]
|
||
|
testDir = 'errors/'
|
||
|
expectErrors = true
|
||
|
}
|
||
|
|
||
|
task testRhinoChyby(type: RhinoTest) {
|
||
|
options = [ '--strict-math=true', '--strict-units=true' ]
|
||
|
testDir = 'chyby/'
|
||
|
// expectErrors = true
|
||
|
}
|
||
|
|
||
|
task testRhinoNoJsError(type: RhinoTest) {
|
||
|
options = [ '--strict-math=true', '--strict-units=true', '--no-js' ]
|
||
|
testDir = 'no-js-errors/'
|
||
|
expectErrors = true
|
||
|
}
|
||
|
|
||
|
task testRhinoLegacy(type: RhinoTest) {
|
||
|
testDir = 'legacy/'
|
||
|
}
|
||
|
|
||
|
task testRhinoStaticUrls(type: RhinoTest) {
|
||
|
options = [ '--strict-math=true', '--rootpath=folder (1)/' ]
|
||
|
testDir = 'static-urls/'
|
||
|
}
|
||
|
|
||
|
task testRhinoCompression(type: RhinoTest) {
|
||
|
options = [ '--compress=true' ]
|
||
|
testDir = 'compression/'
|
||
|
}
|
||
|
|
||
|
task testRhinoSourceMap(type: SourceMapRhinoTest) {
|
||
|
options = [ '--strict-math=true', '--strict-units=true']
|
||
|
testDir = 'sourcemaps/'
|
||
|
}
|
||
|
|
||
|
task setupTest {
|
||
|
dependsOn combineJs
|
||
|
doLast {
|
||
|
file(testOut).deleteDir()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
task clean << {
|
||
|
file(rhinoTestSrc).delete()
|
||
|
file(testOut).deleteDir()
|
||
|
}
|
||
|
|
||
|
class SourceMapRhinoTest extends RhinoTest {
|
||
|
|
||
|
// helper to get the output map file
|
||
|
def getOutputMap(lessFile) {
|
||
|
def outFile = project.file(lessFile.path.replace('test/less', project.testOut).replace('.less', '.css'))
|
||
|
return project.file(outFile.path + ".map");
|
||
|
}
|
||
|
|
||
|
// callback to add SourceMap options to the options list
|
||
|
def postProcessOptions(options, lessFile) {
|
||
|
def outFile = getOutputMap(lessFile)
|
||
|
project.file(outFile.parent).mkdirs()
|
||
|
options << "--source-map=${testDir}${lessFile.name.replace('.less','.css')}"
|
||
|
options << "--source-map-basepath=${lessRootDir}"
|
||
|
options << "--source-map-rootpath=testweb/"
|
||
|
options << "--source-map-output-map-file=${outFile}"
|
||
|
|
||
|
options
|
||
|
}
|
||
|
|
||
|
// Callback to validate output
|
||
|
def handleResult(exec, out, lessFile) {
|
||
|
def actualFile = getOutputMap(lessFile)
|
||
|
def expectedFile = project.file(projectDir + fs + "test" + fs + testDir + fs + lessFile.name.replace(".less", ".json"))
|
||
|
assert actualFile.text == expectedFile.text
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
class DebugRhinoTest extends RhinoTest {
|
||
|
|
||
|
def escapeIt(it) {
|
||
|
return it.replaceAll("\\\\", "\\\\\\\\").replaceAll("/", "\\\\/").replaceAll(":", "\\\\:").replaceAll("\\.", "\\\\.");
|
||
|
}
|
||
|
|
||
|
def globalReplacements(input, directory) {
|
||
|
def pDirectory = toPlatformFs(directory)
|
||
|
def p = lessRootDir + fs + pDirectory
|
||
|
def pathimport = p + toPlatformFs("import/")
|
||
|
def pathesc = escapeIt(p)
|
||
|
def pathimportesc = escapeIt(pathimport)
|
||
|
|
||
|
def result = input.replace("{path}", p).replace("{pathesc}", pathesc).replace("{pathimport}", pathimport)
|
||
|
return result.replace("{pathimportesc}", pathimportesc).replace("\r\n", "\n")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class RhinoTest extends DefaultTask {
|
||
|
|
||
|
RhinoTest() {
|
||
|
dependsOn 'setupTest'
|
||
|
}
|
||
|
|
||
|
def suffix = ""
|
||
|
def testDir = ''
|
||
|
def options = []
|
||
|
def expectErrors = false
|
||
|
def fs = File.separator;
|
||
|
def projectDir = toUpperCaseDriveLetter(System.getProperty("user.dir"));
|
||
|
def lessRootDir = projectDir + fs + "test" + fs + "less"
|
||
|
|
||
|
def toUpperCaseDriveLetter(path) {
|
||
|
if (path.charAt(1)==':' && path.charAt(2)=='\\') {
|
||
|
return path.substring(0,1).toUpperCase() + path.substring(1);
|
||
|
}
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
def toPlatformFs(path) {
|
||
|
return path.replace('\\', fs).replace('/', fs);
|
||
|
}
|
||
|
|
||
|
def expectedCssPath(lessFilePath) {
|
||
|
lessFilePath.replace('.less', "${suffix}.css").replace("${fs}less${fs}", "${fs}css${fs}");
|
||
|
}
|
||
|
|
||
|
def globalReplacements(input, directory) {
|
||
|
return input;
|
||
|
}
|
||
|
|
||
|
def stylize(str, style) {
|
||
|
def styles = [
|
||
|
reset : [0, 0],
|
||
|
bold : [1, 22],
|
||
|
inverse : [7, 27],
|
||
|
underline : [4, 24],
|
||
|
yellow : [33, 39],
|
||
|
green : [32, 39],
|
||
|
red : [31, 39],
|
||
|
grey : [90, 39]
|
||
|
];
|
||
|
return '\033[' + styles[style][0] + 'm' + str +
|
||
|
'\033[' + styles[style][1] + 'm';
|
||
|
}
|
||
|
|
||
|
// Callback for subclasses to make any changes to the options
|
||
|
def postProcessOptions(options, lessFile) {
|
||
|
options
|
||
|
}
|
||
|
|
||
|
// Callback to validate output
|
||
|
def handleResult(exec, out, lessFile) {
|
||
|
def actual = out.toString().trim()
|
||
|
def actualResult = project.file(lessFile.path.replace('test/less', project.testOut).replace('.less', '.css'))
|
||
|
project.file(actualResult.parent).mkdirs()
|
||
|
actualResult << actual
|
||
|
def expected
|
||
|
if (expectErrors) {
|
||
|
assert exec.exitValue != 0
|
||
|
expected = project.file(lessFile.path.replace('.less', '.txt')).text.trim().
|
||
|
replace('{path}', lessFile.parent + '/').
|
||
|
replace('{pathhref}', '').
|
||
|
replace('{404status}', '')
|
||
|
} else {
|
||
|
assert exec.exitValue == 0
|
||
|
def expectedFile = expectedCssPath(lessFile.path)
|
||
|
expected = project.file(expectedFile).text.trim()
|
||
|
expected = globalReplacements(expected, testDir)
|
||
|
}
|
||
|
actual=actual.trim()
|
||
|
actual = actual.replace('\r\n', '\n')
|
||
|
expected = expected.replace('\r\n', '\n')
|
||
|
actual = actual.replace("/","\\")
|
||
|
expected = expected.replace("/","\\")
|
||
|
// println "* actual *"
|
||
|
// println actual
|
||
|
// new File("actual.txt").write(actual)
|
||
|
// println "* expected *"
|
||
|
// println expected
|
||
|
// new File("expected.txt").write(expected)
|
||
|
assert actual == expected
|
||
|
actualResult.delete()
|
||
|
|
||
|
}
|
||
|
|
||
|
@TaskAction
|
||
|
def runTest() {
|
||
|
int testSuccesses = 0, testFailures = 0, testErrors = 0
|
||
|
project.file('test/less/' + testDir).eachFileMatch(FileType.FILES, ~/.*\.less/) { lessFile ->
|
||
|
println "lessfile: $lessFile"
|
||
|
if (!project.hasProperty('test') || lessFile.name.startsWith(project.test)) {
|
||
|
def out = new java.io.ByteArrayOutputStream()
|
||
|
def processedOptions = postProcessOptions([project.rhinoTestSrc, lessFile] + options, lessFile)
|
||
|
def execOptions = {
|
||
|
main = 'org.mozilla.javascript.tools.shell.Main'
|
||
|
// main = 'org.mozilla.javascript.tools.debugger.Main'
|
||
|
classpath = project.configurations.rhino
|
||
|
args = processedOptions
|
||
|
standardOutput = out
|
||
|
ignoreExitValue = true
|
||
|
}
|
||
|
println "rhinoTestSrc: ${project.rhinoTestSrc}"
|
||
|
try {
|
||
|
def exec = project.javaexec(execOptions)
|
||
|
handleResult(exec, out, lessFile)
|
||
|
testSuccesses++
|
||
|
println stylize(' ok', 'green')
|
||
|
}
|
||
|
catch (ex) {
|
||
|
println ex
|
||
|
println()
|
||
|
testErrors++;
|
||
|
}
|
||
|
catch (AssertionError ae) {
|
||
|
println stylize(' failed', 'red')
|
||
|
println ae
|
||
|
testFailures++
|
||
|
}
|
||
|
} else {
|
||
|
println stylize(' skipped', 'yellow')
|
||
|
}
|
||
|
}
|
||
|
println stylize(testSuccesses + ' ok', 'green')
|
||
|
println stylize(testFailures + ' assertion failed', testFailures == 0 ? 'green' : 'red')
|
||
|
println stylize(testErrors + ' errors', testErrors == 0 ? 'green' : 'red')
|
||
|
if (testFailures != 0 || testErrors != 0) {
|
||
|
project.failures++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class AllRhinoTests extends DefaultTask {
|
||
|
|
||
|
AllRhinoTests() {
|
||
|
}
|
||
|
|
||
|
@TaskAction
|
||
|
def runTest() {
|
||
|
println stylize(project.failures + ' test suites failed', project.failures == 0 ? 'green' : 'red')
|
||
|
}
|
||
|
|
||
|
def stylize(str, style) {
|
||
|
def styles = [
|
||
|
reset : [0, 0],
|
||
|
bold : [1, 22],
|
||
|
inverse : [7, 27],
|
||
|
underline : [4, 24],
|
||
|
yellow : [33, 39],
|
||
|
green : [32, 39],
|
||
|
red : [31, 39],
|
||
|
grey : [90, 39]
|
||
|
];
|
||
|
return '\033[' + styles[style][0] + 'm' + str +
|
||
|
'\033[' + styles[style][1] + 'm';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class GruntTask extends Exec {
|
||
|
private String gruntExecutable = Os.isFamily(Os.FAMILY_WINDOWS) ? "grunt.cmd" : "grunt"
|
||
|
private String switches = "--no-color"
|
||
|
|
||
|
String gruntArgs = ""
|
||
|
|
||
|
public GruntTask() {
|
||
|
super()
|
||
|
this.setExecutable(gruntExecutable)
|
||
|
}
|
||
|
|
||
|
public void setGruntArgs(String gruntArgs) {
|
||
|
this.args = "$switches $gruntArgs".trim().split(" ") as List
|
||
|
}
|
||
|
}
|
||
|
|