diff --git a/src/main/groovy/org/groocss/Comment.groovy b/src/main/groovy/org/groocss/Comment.groovy index 0fee2fd..12c3947 100644 --- a/src/main/groovy/org/groocss/Comment.groovy +++ b/src/main/groovy/org/groocss/Comment.groovy @@ -5,7 +5,7 @@ import groovy.transform.EqualsAndHashCode import groovy.transform.TupleConstructor /** - * Created by adavis on 8/9/17. + * Represents a comment to include in output. Created by adavis on 8/9/17. */ @TupleConstructor @EqualsAndHashCode @@ -13,5 +13,5 @@ import groovy.transform.TupleConstructor class Comment { String comment boolean isEmpty() { comment == '' } - String toString() { "/**$comment*/" } + String toString() { "/* $comment */" } } diff --git a/src/main/groovy/org/groocss/GrooCSS.groovy b/src/main/groovy/org/groocss/GrooCSS.groovy index 9b1c0fc..200d0cf 100644 --- a/src/main/groovy/org/groocss/GrooCSS.groovy +++ b/src/main/groovy/org/groocss/GrooCSS.groovy @@ -1744,4 +1744,38 @@ class GrooCSS extends Script { r } + /** Adds a comment to be included in output. */ + Comment comment(String comment) { + def com = new Comment(comment) + currentCss << com + com + } + + /** Imports given Groocss file at filename. */ + MediaCSS importFile(Map params = [:], String filename) { importReader params, new File(filename).newReader() } + + /** Imports given Groocss file. */ + MediaCSS importFile(Map params = [:], File file) { importReader params, file.newReader() } + + /** Imports given Groocss. */ + MediaCSS importString(Map params = [:], String groocss) { importReader(params, new StringReader(groocss)) } + + /** Imports given Groocss input using given Reader. */ + MediaCSS importReader(Map params = [:], Reader reader) { + def shell = makeShell() + def script = shell.parse(reader) + def binding = new Binding() + params.each { binding.setVariable(it.key, it.value) } + script.binding = binding + script.invokeMethod('setConfig', css.config) + script.run() + MediaCSS other = (MediaCSS) script.getProperty('css') + currentCss.add other + } + + /** Imports given Groocss file using given InputStream. */ + MediaCSS importStream(Map params = [:], InputStream stream) { + importReader params, new InputStreamReader(stream) + } + } diff --git a/src/main/groovy/org/groocss/MediaCSS.groovy b/src/main/groovy/org/groocss/MediaCSS.groovy index 28b30e8..7121cfa 100644 --- a/src/main/groovy/org/groocss/MediaCSS.groovy +++ b/src/main/groovy/org/groocss/MediaCSS.groovy @@ -60,11 +60,13 @@ class MediaCSS { else writer.append (groups.findAll{ !it.isEmpty() }.join(sn)) if (kfs) writer.append((groups || fonts) ? sn : '').append (kfs.join(sn)) - if (otherCss) + if (otherCss) { + if (groups || fonts || kfs) writer.append(sn) otherCss.each { it.writeTo(writer) writer.append(sn) } + } } /** Creates a new StyleGroup element and runs given closure on it. */ diff --git a/src/test/groovy/org/groocss/CommentSpec.groovy b/src/test/groovy/org/groocss/CommentSpec.groovy new file mode 100644 index 0000000..871e0ae --- /dev/null +++ b/src/test/groovy/org/groocss/CommentSpec.groovy @@ -0,0 +1,34 @@ +package org.groocss + +import spock.lang.Specification + +/** + * Created by adavis on 8/10/17. + */ +class CommentSpec extends Specification { + + def "comment should include comment in output"() { + given: + def css = GrooCSS.process { + comment 'I am Groocss!' + } + expect: + '/* I am Groocss! */' == "$css" + } + + def "comment should print in order"() { + given: + def css = GrooCSS.process { + comment 'comment1' + a { fontSize 18.px } + comment 'comment2' + aside { fontSize 15.px } + } + expect: + "$css" == ''' + /* comment1 */ + a{font-size: 18px;} + /* comment2 */ + aside{font-size: 15px;}'''.stripIndent().trim() + } +} diff --git a/src/test/groovy/org/groocss/GroocssSpec.groovy b/src/test/groovy/org/groocss/GroocssSpec.groovy index 3f15d70..5faeef4 100644 --- a/src/test/groovy/org/groocss/GroocssSpec.groovy +++ b/src/test/groovy/org/groocss/GroocssSpec.groovy @@ -613,7 +613,7 @@ class GroocssSpec extends Specification { } } then: - "$css" == 'form{font-size: 2em;}@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' + "$css" == 'form{font-size: 2em;}\n@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' } def "should use minus to remove styles"() { @@ -628,7 +628,7 @@ class GroocssSpec extends Specification { } } then: - "$css" == 'form{font-size: 2em;}@media mobile {\nform{line-height: 1.1em;}\n}\n' + "$css" == 'form{font-size: 2em;}\n@media mobile {\nform{line-height: 1.1em;}\n}\n' } def "removing empty styles has no effect"() { @@ -643,7 +643,7 @@ class GroocssSpec extends Specification { } } then: - "$css" == 'form{font-size: 2em;}@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' + "$css" == 'form{font-size: 2em;}\n@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' } def "removing non-matching styles has no effect"() { @@ -658,7 +658,7 @@ class GroocssSpec extends Specification { } } then: - "$css" == 'form{font-size: 2em;}@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' + "$css" == 'form{font-size: 2em;}\n@media mobile {\nform{font-size: 2em;\n\tline-height: 1.1em;}\n}\n' } def "styles math is idempotent"() { @@ -673,7 +673,7 @@ class GroocssSpec extends Specification { } } then: - "$css" == 'form{font-size: 2em;}' + + "$css" == 'form{font-size: 2em;}\n' + '@media mobile {\nform{line-height: 1.1em;}\n}\n' + '@media only screen and (max-width: 960px) {\n' + 'form{font-size: 2em;\n\tline-height: 12pt;}\n' + diff --git a/src/test/groovy/org/groocss/ImportSpec.groovy b/src/test/groovy/org/groocss/ImportSpec.groovy new file mode 100644 index 0000000..d03d048 --- /dev/null +++ b/src/test/groovy/org/groocss/ImportSpec.groovy @@ -0,0 +1,70 @@ +package org.groocss + +import spock.lang.Shared +import spock.lang.Specification +import spock.lang.Unroll + +/** + * Created by adavis on 8/10/17. + */ +class ImportSpec extends Specification { + + @Shared + File otherCss + + def setup() { + otherCss = new File(File.createTempDir(),"other.css") + } + + @Unroll + def "import should just import it: #name"() { + given: + otherCss.text = "a {color blue}" + expect: + def css = GrooCSS.process closure + 'a{color: Blue;}' == "$css".trim() + where: + name | closure + 'File name' | { importFile otherCss.absoluteFile.toString() } + 'File' | { importFile otherCss.absoluteFile } + 'String' | { importString otherCss.text } + 'InputStream' | { importStream otherCss.newInputStream() } + } + + def "import should be put last"() { + given: + otherCss.text = "a {color blue}" + expect: + def css = GrooCSS.process { + importFile otherCss.absoluteFile + header { fontSize '15pt' } + } + 'header{font-size: 15pt;}\na{color: Blue;}' == "$css".trim() + } + + def "import should allow parameters"() { + given: + otherCss.text = "a {color linkColor}" + expect: + def css = GrooCSS.process { + importFile otherCss.absoluteFile, linkColor: '#456789' + } + 'a{color: #456789;}' == "$css".trim() + } + + @Unroll + def "import should allow #type parameter"() { + given: + otherCss.text = "a {color linkColor}" + expect: + def css = GrooCSS.process { + importFile otherCss.absoluteFile, linkColor: value, param2: 123 + } + 'a{color: #123456;}' == "$css".trim() + where: + type | value + 'String' | '#123456' + 'Integer' | 0x123456 + 'Color' | new Color(0x123456) + } +} diff --git a/src/test/groovy/org/groocss/RawSpec.groovy b/src/test/groovy/org/groocss/RawSpec.groovy index 4948a6e..c3b1318 100644 --- a/src/test/groovy/org/groocss/RawSpec.groovy +++ b/src/test/groovy/org/groocss/RawSpec.groovy @@ -15,4 +15,14 @@ class RawSpec extends Specification { expect: '::webkit-blaw { dostuff }' == "$css" } + + def "raw should print in order"() { + given: + def css = GrooCSS.process { + raw 'raw1' + raw 'raw2' + } + expect: + 'raw1\nraw2' == "$css" + } }