assetbuild 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ demo/compressed.css
2
+ demo/normal.css
3
+ pkg/
4
+ demo/*.build.*
@@ -0,0 +1,28 @@
1
+ Manifest
2
+ README
3
+ Rakefile
4
+ assetbuild.gemspec
5
+ bin/assetbuild
6
+ bin/buildcoffee
7
+ bin/buildcss
8
+ demo/assetbuild.yml
9
+ demo/assets.css
10
+ demo/coffee_bundle/demo.coffee
11
+ demo/coffee_bundle/demo2.coffee
12
+ demo/main.js
13
+ demo/secondary.css
14
+ demo/stand_alone.coffee
15
+ demo/stand_alone.js
16
+ demo/styles/reset.css
17
+ demo/styles/special/basic_stuff.css
18
+ demo/styles/special/more_stuff.css
19
+ demo/styles/typography.css
20
+ demo/test.build.css
21
+ demo/test.build.min.css
22
+ demo/test.css
23
+ lib/asset_build.rb
24
+ lib/asset_build/coffee_bundler.rb
25
+ lib/asset_build/css_reader.rb
26
+ spec/asset_build_spec.rb
27
+ spec/coffee_bundler_spec.rb
28
+ spec/css_reader_spec.rb
data/README ADDED
@@ -0,0 +1,55 @@
1
+ Builds, bundles, and minifies CSS and CoffeeScript files.
2
+
3
+ == Building CSS
4
+
5
+ > require 'css-reader'
6
+ > css = CSSReader.new("test.css","secondary.css")
7
+ > css.save("production.css", :compress => true)
8
+
9
+ The above commands will generate new file that merges the files passed to the class in order. Also, and "@import" statement is processed inline and is also inserted in the order it is encountered recursively throughout the CSS. In this example the file has also been yui-compressed.
10
+
11
+ Alternatively, you can pass in additional css files at later point with the append method:
12
+
13
+ > css = CSSReader.new("test.css")
14
+ > # do stuff...
15
+ > css.append("secondary.css")
16
+
17
+ You could also run this from the command line:
18
+
19
+ > buildcss public/stylesheets/main.css -c
20
+
21
+ Which will recursively process all imported files and then write a single minified CSS file to:
22
+ public/stylesheets/main.build.min.css
23
+
24
+ == Building CoffeeScript
25
+
26
+ > require 'coffee-bundler'
27
+ > js = CoffeeBundler.new("path/to/coffee/bundle")
28
+ > js.save("public/javascripts/bundle.min.js", :compress => true)
29
+
30
+ This will effectively bundle files that match:
31
+ path/to/coffee/bundle/*.coffee
32
+
33
+ ...into a single minified JS file located at:
34
+ public/javascripts/bundle.min.js
35
+
36
+ No, this will not work unless you have coffee-script installed on your system!
37
+
38
+ == Dependencies
39
+
40
+ Requires the yui-compressor gem:
41
+
42
+ > gem install -r yui-compressor
43
+
44
+ More info:
45
+ http://github.com/sstephenson/ruby-yui-compressor
46
+
47
+ == Specs
48
+
49
+ A simple but comprehensive rSpec suite is provided for quality assurance purposes.
50
+
51
+ > spec css_reader_spec.rb
52
+
53
+ == Disclaimer
54
+
55
+ This is really crude but useful. You could easily crash it if you placed an @import statement in a fashion to create an infinite loop. Don't do that! :)
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ # Rakefile
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gemspec|
8
+ gemspec.name = "assetbuild"
9
+ gemspec.summary = "Easily merge and compress multiple asset files together (currently supports CSS and coffee-script)."
10
+ gemspec.homepage = "http://github.com/jimjeffers/assetbuild"
11
+ gemspec.authors = ["Jim Jeffers"]
12
+ gemspec.description = "Easily merge and compress multiple asset files together (currently supports CSS and coffee-script)."
13
+ gemspec.email = "shout@jimjeffers.com"
14
+ gemspec.executables = ["assetbuild", "buildcoffee", "buildcss"]
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
19
+ end
20
+
21
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
6
+
7
+ # Argument defaults
8
+ options = {
9
+ :individual => false,
10
+ :compress => false
11
+ }
12
+
13
+ # Get arguments
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "usage: assetbuild path_to_yml"
16
+ o.separator ""
17
+
18
+ # Version
19
+ o.on_tail("-v", "--version", "show version") do
20
+ #puts "assetbuild " + AssetBuild.version
21
+ exit
22
+ end
23
+ end
24
+
25
+ opts.parse! # Parse arguments into `options` hash
26
+
27
+ # Get source from command line
28
+ files = []
29
+ ARGV.each do |arg|
30
+ if arg[0] == "-"
31
+ break
32
+ else
33
+ # TODO: Find a cleaner way to do this. I know there has to be one.
34
+ builder = AssetBuild.new(File.expand_path(File.join(ENV["PWD"],arg)))
35
+ builder.process_files!
36
+ end
37
+ end
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
6
+
7
+ # Argument defaults
8
+ options = {
9
+ :individual => false,
10
+ :compress => false
11
+ }
12
+
13
+ # Get arguments
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "usage: buildcoffee source [destination] [--compress]"
16
+ o.separator ""
17
+
18
+ # Use YUI compression?
19
+ o.on("-c", "--compress", "compress javascript with yui-compressor") do
20
+ options[:compress] = true
21
+ end
22
+
23
+ # Version
24
+ o.on_tail("-v", "--version", "show version") do
25
+ #puts "coffeebundler " + CoffeeBundler.version
26
+ exit
27
+ end
28
+ end
29
+
30
+ opts.parse! # Parse arguments into `options` hash
31
+
32
+ # Get source from command line
33
+ files = []
34
+ ARGV.each do |arg|
35
+ if arg[0] == "-"
36
+ break
37
+ else
38
+ tags = (options[:compress]) ? 'build.min' : 'build'
39
+ if File.directory?(arg)
40
+ destination = [arg]+tags+["js"].join(".")
41
+ else
42
+ filename = File.basename(arg)
43
+ destination = filename.split(".").insert(-2,tags).join('.')
44
+ end
45
+ # TODO: Find a cleaner way to do this. I know there has to be one.
46
+ files << [ File.expand_path(File.join(ENV["PWD"],arg)),
47
+ File.expand_path(File.join(ENV["PWD"],File.dirname(arg),destination))]
48
+ end
49
+ end
50
+
51
+ unless options[:individual] || files.length < 1
52
+ CoffeeBundler.new(files.map { |m| m[0] }).save(files.first[1],:compress => options[:compress])
53
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
6
+
7
+ # Argument defaults
8
+ options = {
9
+ :individual => false,
10
+ :compress => false
11
+ }
12
+
13
+ # Get arguments
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "usage: buildcss source [destination] [--compress]"
16
+ o.separator ""
17
+
18
+ # Use YUI compression?
19
+ o.on("-c", "--compress", "compress css with yui-compressor") do
20
+ options[:compress] = true
21
+ end
22
+
23
+ # Process files individually?
24
+ o.on("--individual", "process each file individually rather than merge together") do
25
+ options[:individual] = true
26
+ end
27
+
28
+ # Version
29
+ o.on_tail("-v", "--version", "show version") do
30
+ #puts "cssbuild " + CSSReader.version
31
+ exit
32
+ end
33
+ end
34
+
35
+ opts.parse! # Parse arguments into `options` hash
36
+
37
+ # Get source from command line
38
+ files = []
39
+ ARGV.each do |arg|
40
+ if arg[0] == "-"
41
+ break
42
+ else
43
+ filename = File.basename(arg)
44
+ tags = (options[:compress]) ? 'build.min' : 'build'
45
+ destination = filename.split(".").insert(-2,tags).join('.')
46
+ # TODO: Find a cleaner way to do this. I know there has to be one.
47
+ files << [ File.expand_path(File.join(ENV["PWD"],arg)),
48
+ File.expand_path(File.join(ENV["PWD"],File.dirname(arg),destination))]
49
+ end
50
+ end
51
+
52
+ unless options[:individual] || files.length < 1
53
+ CSSReader.new(files.map { |m| m[0] }).save(files.first[1],:compress => options[:compress])
54
+ end
@@ -0,0 +1,15 @@
1
+ main.js:
2
+ type: coffeescript
3
+ source: coffee_bundle
4
+ compress: true
5
+
6
+ stand_alone.js:
7
+ type: coffeescript
8
+ source: stand_alone.coffee
9
+ desintation: coffee_bundle/
10
+ compress: true
11
+
12
+ assets.css:
13
+ type: stylesheet
14
+ source: test.css
15
+ compress: true
@@ -0,0 +1 @@
1
+ *{border:0;margin:0;padding:0;}body{font:75% "Lucida Grande","Trebuchet MS",Verdana,sans-serif;}#basic{box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);-o-box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);-icab-box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);-khtml-box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);-moz-box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);-webkit-box-shadow:3px 2px blur color/#000/rgba(0,0,0,.5);}#more{border:1px solid #999;}#primary_content{left:50%;position:absolute;top:50%;width:100px;}
@@ -0,0 +1,29 @@
1
+ # Assignment:
2
+ number: 42
3
+ opposite_day: true
4
+
5
+ # Conditions:
6
+ number: -42 if opposite_day
7
+
8
+ # Functions:
9
+ square: (x) -> x * x
10
+
11
+ # Arrays:
12
+ list: [1, 2, 3, 4, 5]
13
+
14
+ # Objects:
15
+ math: {
16
+ root: Math.sqrt
17
+ square: square
18
+ cube: (x) -> x * square x
19
+ }
20
+
21
+ # Splats:
22
+ race: (winner, runners...) ->
23
+ print winner, runners
24
+
25
+ # Existence:
26
+ alert "I knew it!" if elvis?
27
+
28
+ # Array comprehensions:
29
+ cubed_list: math.cube num for num in list
@@ -0,0 +1,25 @@
1
+ class Animal
2
+ move: (meters) ->
3
+ alert @name + " moved " + meters + "m."
4
+
5
+ class Snake extends Animal
6
+ constructor: (name) ->
7
+ @name: name
8
+
9
+ move: ->
10
+ alert "Slithering..."
11
+ super 5
12
+
13
+ class Horse extends Animal
14
+ constructor: (name) ->
15
+ @name: name
16
+
17
+ move: ->
18
+ alert "Galloping..."
19
+ super 45
20
+
21
+ sam: new Snake "Sammy the Python"
22
+ tom: new Horse "Tommy the Palomino"
23
+
24
+ sam.move()
25
+ tom.move()
@@ -0,0 +1 @@
1
+ (function(){var _a,_b,_c,_d,cubed_list,list,math,num,number,opposite_day,race,square;number=42;opposite_day=true;if(opposite_day){number=-42}square=function square(x){return x*x};list=[1,2,3,4,5];math={root:Math.sqrt,square:square,cube:function cube(x){return x*square(x)}};race=function race(winner){var runners;runners=Array.prototype.slice.call(arguments,1);return print(winner,runners)};if((typeof elvis!=="undefined"&&elvis!==null)){alert("I knew it!")}cubed_list=(function(){_a=[];_b=list;for(_c=0,_d=_b.length;_c<_d;_c++){num=_b[_c];_a.push(math.cube(num))}return _a}).call(this)})();(function(){var Animal,Horse,Snake,sam,tom;var __extends=function(child,parent){var ctor=function(){};ctor.prototype=parent.prototype;child.__superClass__=parent.prototype;child.prototype=new ctor();child.prototype.constructor=child};Animal=function Animal(){};Animal.prototype.move=function move(meters){return alert(this.name+" moved "+meters+"m.")};Snake=function Snake(name){this.name=name;return this};__extends(Snake,Animal);Snake.prototype.move=function move(){alert("Slithering...");return Snake.__superClass__.move.call(this,5)};Horse=function Horse(name){this.name=name;return this};__extends(Horse,Animal);Horse.prototype.move=function move(){alert("Galloping...");return Horse.__superClass__.move.call(this,45)};sam=new Snake("Sammy the Python");tom=new Horse("Tommy the Palomino");sam.move();tom.move()})();
@@ -0,0 +1,5 @@
1
+ /* Some more CSS could go in here I suppose. */
2
+
3
+ .secondary {
4
+ width: 100px;
5
+ }
@@ -0,0 +1,13 @@
1
+ futurists: {
2
+ sculptor: "Umberto Boccioni"
3
+ painter: "Vladimir Burliuk"
4
+ poet: {
5
+ name: "F.T. Marinetti"
6
+ address: [
7
+ "Via Roma 42R"
8
+ "Bellagio, Italy 22021"
9
+ ]
10
+ }
11
+ }
12
+
13
+ {poet: {name: poet, address: [street, city]}}: futurists
@@ -0,0 +1 @@
1
+ (function(){var _a,_b,_c,city,futurists,poet,street;futurists={sculptor:"Umberto Boccioni",painter:"Vladimir Burliuk",poet:{name:"F.T. Marinetti",address:["Via Roma 42R","Bellagio, Italy 22021"]}};_a=futurists;_b=_a.poet;poet=_b.name;_c=_b.address;street=_c[0];city=_c[1]})();
@@ -0,0 +1,11 @@
1
+ /* Reset
2
+ Updated: Wed 02.06.10 @ 12:15 a.m.
3
+ Author: Jim Jeffers
4
+ ----------------------------------------------------*/
5
+ * {
6
+ border: 0;
7
+ margin: 0;
8
+ padding: 0;
9
+ }
10
+
11
+ @import "typography.css";
@@ -0,0 +1,14 @@
1
+ /* Basic Stuff
2
+ Updated: Thu 10.18.07 @ 5:15 p.m.
3
+ Author: OK ok..
4
+ ----------------------------------------------------*/
5
+ #basic {
6
+ box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
7
+ -o-box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
8
+ -icab-box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
9
+ -khtml-box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
10
+ -moz-box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
11
+ -webkit-box-shadow: 3px 2px blur color/#000/rgba(0,0,0,.5);
12
+ }
13
+
14
+ @import "more_stuff.css";
@@ -0,0 +1,5 @@
1
+ /* =MORE STUFF
2
+ ------------------------------------------------------ */
3
+ #more {
4
+ border: 1px solid #999;
5
+ }
@@ -0,0 +1,10 @@
1
+ /* Typography
2
+ Updated: Wed 02.06.10 @ 12:15 a.m.
3
+ Author: Jim Jeffers
4
+ ----------------------------------------------------*/
5
+
6
+ body {
7
+ font: 75% "Lucida Grande", "Trebuchet MS", Verdana, sans-serif;
8
+ }
9
+
10
+ @import "special/basic_stuff.css";
@@ -0,0 +1,31 @@
1
+ /* KEEP OUR CSS CLEAN
2
+ Some guidelines to follow:
3
+ 1. Break code down into sections.
4
+ 2. Keep your rules alphabetically sorted.
5
+ 3. Only put one selector per line for a block of rules that apply to multiple selectors.
6
+ 4. Indent your rules, only one rule per line.
7
+ 5. Indent proprietary properties with two spaces. Keep these properties directly below the proposed property.
8
+
9
+ example:
10
+
11
+ element#id,
12
+ element.class {
13
+ rule1: value;
14
+ -webkit-rule2: value;
15
+ -moz-rule2: value;
16
+ rule2: value;
17
+ top: value;
18
+ }
19
+ */
20
+ /* =IMPORT DEPENDENCIES
21
+ ------------------------------------------------------ */
22
+ @import "styles/reset.css";
23
+
24
+ /* =PRIMARY_CONTENT
25
+ ------------------------------------------------------ */
26
+ #primary_content {
27
+ left: 50%;
28
+ position: absolute;
29
+ top: 50%;
30
+ width: 100px;
31
+ }
@@ -0,0 +1,26 @@
1
+ require 'asset_build/coffee_bundler'
2
+ require 'asset_build/css_reader'
3
+
4
+ class AssetBuild
5
+ attr_accessor :manifest
6
+
7
+ def initialize(path)
8
+ @manifest = YAML::load(File.open(path).readlines.join(""))
9
+ @path = File.dirname(path)
10
+ end
11
+
12
+ def process_files!
13
+ @manifest.each do |destination,options|
14
+ compressed = options["compress"] || false
15
+ if options["type"] == "coffeescript"
16
+ coffee_bundler = CoffeeBundler.new(File.join(@path,options["source"]))
17
+ coffee_bundler.save(File.join(@path,destination),:compress => compressed)
18
+ puts File.join(@path,destination)
19
+ elsif options["type"] == "stylesheet"
20
+ css_reader = CSSReader.new(File.join(@path,options["source"]))
21
+ css_reader.save(File.join(@path,destination),:compress => compressed)
22
+ puts File.join(@path,destination)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ require "rubygems"
2
+ require "yui/compressor"
3
+
4
+ class CoffeeBundler
5
+ def initialize(*args)
6
+ @@yui = YUI::JavaScriptCompressor.new
7
+ @files = {}
8
+ @processed_js = []
9
+ append(*args)
10
+ end
11
+
12
+ def append(*args)
13
+ unless args.nil? || args.length < 1
14
+ if args.length == 1
15
+ args = args[0] if args.class == Array
16
+ args = [args] if args.class == String
17
+ end
18
+ for path in args
19
+ if File.directory?(path)
20
+ for inner_path in Dir.glob(File.join(path,'*.coffee')).to_a
21
+ process_path(inner_path)
22
+ end
23
+ else
24
+ process_path(path)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def to_javascript
31
+ @files.sort{|a,b| a[1][:position]<=>b[1][:position]}.map{ |path,values| values[:contents] }.join("")
32
+ end
33
+
34
+ def compressed
35
+ @@yui.compress(to_javascript)
36
+ end
37
+
38
+ def save(name,options={})
39
+ compress = options[:compress] || false
40
+ File.open(name,'w') {|f| f.write compress ? compressed : to_javascript }
41
+ end
42
+
43
+ protected
44
+ def compile(path)
45
+ %x(coffee -p #{path})
46
+ end
47
+
48
+ def process_path(path)
49
+ unless @files.keys.include?(path)
50
+ @files[path] = {
51
+ :name => File.basename(path),
52
+ :directory => File.dirname(path),
53
+ :contents => compile(path),
54
+ :position => @files.length
55
+ }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,60 @@
1
+ require "rubygems"
2
+ require "yui/compressor"
3
+
4
+ class CSSReader
5
+ def initialize(*args)
6
+ @@yui = YUI::CssCompressor.new
7
+ @files = {}
8
+ @processed_css = []
9
+ append(*args)
10
+ end
11
+
12
+ def append(*args)
13
+ unless args.nil? || args.length < 1
14
+ if args.length == 1
15
+ args = args[0] if args.class == Array
16
+ args = [args] if args.class == String
17
+ end
18
+ for path in args
19
+ file = File.open(path)
20
+ unless @files.keys.include?(path)
21
+ process_imports( @files[path] = {
22
+ :name => File.basename(path),
23
+ :directory => File.dirname(path),
24
+ :contents => file.readlines,
25
+ :position => @files.length } )
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def stylesheets
32
+ @files.map { |path,values| values[:name] }
33
+ end
34
+
35
+ def normal
36
+ @processed_css.join("")
37
+ end
38
+
39
+ def compressed
40
+ @@yui.compress(normal)
41
+ end
42
+
43
+ def save(name,options={})
44
+ compress = options[:compress] || false
45
+ File.open(name,'w') {|f| f.write compress ? compressed : normal }
46
+ end
47
+
48
+ protected
49
+ def process_imports(file)
50
+ file[:contents].each do |line|
51
+ if line =~ /@import.*;/
52
+ file_name = eval(line.match(/".*?"/)[0])
53
+ file_path = [file[:directory],file_name].join("/")
54
+ append(file_path)
55
+ else
56
+ @processed_css << line
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
2
+
3
+ describe AssetBuild do
4
+ it "should be defined" do
5
+ defined?(AssetBuild).nil?.should be(false)
6
+ end
7
+
8
+ before(:all) do
9
+ @manifest_path = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','assetbuild.yml'))
10
+ @asset_build = AssetBuild.new(@manifest_path)
11
+ end
12
+
13
+ describe "initialize" do
14
+ it "should know where to put destination files" do
15
+ @asset_build.process_files!
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
2
+
3
+ describe CoffeeBundler do
4
+ it "should be defined" do
5
+ defined?(CoffeeBundler).nil?.should be(false)
6
+ end
7
+
8
+ before(:all) do
9
+ @bundle_path = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','coffee_bundle'))
10
+ @coffee_bundler = CoffeeBundler.new(@bundle_path)
11
+ end
12
+
13
+ describe "to_javascript" do
14
+ it "should compile to javascript" do
15
+ (@coffee_bundler.to_javascript.index("function()") > 0).should be(true)
16
+ end
17
+
18
+ it "should have 'cubed_list' before 'Animal'" do
19
+ (@coffee_bundler.to_javascript.index("cubed_list") < @coffee_bundler.to_javascript.index("Animal")).should be(true)
20
+ end
21
+
22
+ it "should retain comments as javascript" do
23
+ (@coffee_bundler.to_javascript.index("//") > 0).should be(true)
24
+ end
25
+
26
+ it "should be able to process a stand alone file" do
27
+ @coffee_bundler = CoffeeBundler.new(File.expand_path(File.join(File.dirname(__FILE__),'..','demo','stand_alone.coffee')))
28
+ (@coffee_bundler.to_javascript.index("var _a, _b, _c, city, futurists, poet, street;") > 0).should be(true)
29
+ end
30
+ end
31
+
32
+ describe "compressed" do
33
+ it "should not retain comments when compressed" do
34
+ (@coffee_bundler.compressed.index("//").nil?).should be(true)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,140 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','asset_build'))
2
+
3
+ describe CSSReader do
4
+ it "should be defined" do
5
+ defined?(CSSReader).nil?.should be(false)
6
+ end
7
+
8
+ describe "stylesheets" do
9
+ before(:all) do
10
+ @test_path = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','test.css'))
11
+ @secondary_path = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','secondary.css'))
12
+ @css_reader = CSSReader.new(@test_path)
13
+ end
14
+
15
+ it "should include test.css" do
16
+ @css_reader.stylesheets.include?("test.css").should be(true)
17
+ end
18
+
19
+ it "should include reset.css" do
20
+ @css_reader.stylesheets.include?("reset.css").should be(true)
21
+ end
22
+
23
+ it "should include typography.css" do
24
+ @css_reader.stylesheets.include?("typography.css").should be(true)
25
+ end
26
+
27
+ it "should include basic_stuff.css" do
28
+ @css_reader.stylesheets.include?("basic_stuff.css").should be(true)
29
+ end
30
+
31
+ it "should include basic_stuff.css" do
32
+ @css_reader.stylesheets.include?("more_stuff.css").should be(true)
33
+ end
34
+
35
+ it "should not include secondary.css" do
36
+ @css_reader.stylesheets.include?("secondary.css").should be(false)
37
+ end
38
+
39
+ it "should include secondary.css if we append it" do
40
+ @css_reader.append(@secondary_path)
41
+ @css_reader.stylesheets.include?("secondary.css").should be(true)
42
+ end
43
+
44
+ it "should include secondary.css if we open multiple docs on initialize" do
45
+ @css_reader = CSSReader.new(@test_path,@secondary_path)
46
+ @css_reader.stylesheets.include?("secondary.css").should be(true)
47
+ end
48
+
49
+ describe "normal" do
50
+ before(:all) do
51
+ @css_text = @css_reader.normal
52
+ end
53
+
54
+ it "should have '\#basic' before '\#more'" do
55
+ (@css_text.index("\#basic") < @css_text.index("\#more")).should be(true)
56
+ end
57
+
58
+ it "should 'body' before '\#basic'" do
59
+ (@css_text.index("body") < @css_text.index("\#basic")).should be(true)
60
+ end
61
+
62
+ it "should 'border: 0;' before 'body'" do
63
+ (@css_text.index("border: 0;") < @css_text.index("body")).should be(true)
64
+ end
65
+
66
+ it "should have '\#basic' before '\#primary_content'" do
67
+ (@css_text.index("\#basic") < @css_text.index("\#primary_content")).should be(true)
68
+ end
69
+
70
+ it "should not contain and @import statements" do
71
+ @css_text.match(/@import./).should be(nil)
72
+ end
73
+
74
+ it "should have new lines" do
75
+ @css_text.match(/\n/).nil?.should be(false)
76
+ end
77
+
78
+ it "should have comments" do
79
+ @css_text.match(/\/\*.*/).nil?.should be(false)
80
+ end
81
+ end
82
+
83
+ describe "compressed" do
84
+ before(:all) do
85
+ @css_text = @css_reader.compressed
86
+ end
87
+
88
+ it "should not have any new lines" do
89
+ @css_text.match(/\n/).should be(nil)
90
+ end
91
+
92
+ it "should not have any comments" do
93
+ @css_text.match(/\/\*.*/).should be(nil)
94
+ end
95
+ end
96
+
97
+ describe "save" do
98
+ before(:all) do
99
+ @normal = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','normal.css'))
100
+ @compressed = File.expand_path(File.join(File.dirname(__FILE__),'..','demo','compressed.css'))
101
+ @css_reader.save(@normal)
102
+ @css_reader.save(@compressed, :compress => true)
103
+ end
104
+
105
+ it "should create a new file with the name 'normal.css'" do
106
+ File.exists?(@normal).should be(true)
107
+ end
108
+
109
+ it "should create a new file with the name 'compressed.css'" do
110
+ File.exists?(@compressed).should be(true)
111
+ end
112
+
113
+ describe "compressed file" do
114
+ before(:all) do
115
+ @css_text = File.open(@compressed,"r").readlines.join("\n")
116
+ end
117
+ it "should not have any new lines" do
118
+ @css_text.match(/\n/).should be(nil)
119
+ end
120
+
121
+ it "should not have any comments" do
122
+ @css_text.match(/\/\*.*/).should be(nil)
123
+ end
124
+ end
125
+
126
+ describe "normal file" do
127
+ before(:all) do
128
+ @css_text = File.open(@normal,"r").readlines.join("\n")
129
+ end
130
+ it "should have new lines" do
131
+ @css_text.match(/\n/).nil?.should be(false)
132
+ end
133
+
134
+ it "should have comments" do
135
+ @css_text.match(/\/\*.*/).nil?.should be(false)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: assetbuild
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Jim Jeffers
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-08 00:00:00 +10:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Easily merge and compress multiple asset files together (currently supports CSS and coffee-script).
22
+ email: shout@jimjeffers.com
23
+ executables:
24
+ - assetbuild
25
+ - buildcoffee
26
+ - buildcss
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - README
31
+ files:
32
+ - .gitignore
33
+ - Manifest
34
+ - README
35
+ - Rakefile
36
+ - VERSION
37
+ - bin/assetbuild
38
+ - bin/buildcoffee
39
+ - bin/buildcss
40
+ - demo/assetbuild.yml
41
+ - demo/assets.css
42
+ - demo/coffee_bundle/demo.coffee
43
+ - demo/coffee_bundle/demo2.coffee
44
+ - demo/main.js
45
+ - demo/secondary.css
46
+ - demo/stand_alone.coffee
47
+ - demo/stand_alone.js
48
+ - demo/styles/reset.css
49
+ - demo/styles/special/basic_stuff.css
50
+ - demo/styles/special/more_stuff.css
51
+ - demo/styles/typography.css
52
+ - demo/test.css
53
+ - lib/asset_build.rb
54
+ - lib/asset_build/coffee_bundler.rb
55
+ - lib/asset_build/css_reader.rb
56
+ - spec/asset_build_spec.rb
57
+ - spec/coffee_bundler_spec.rb
58
+ - spec/css_reader_spec.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/jimjeffers/assetbuild
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.6
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Easily merge and compress multiple asset files together (currently supports CSS and coffee-script).
89
+ test_files:
90
+ - spec/asset_build_spec.rb
91
+ - spec/coffee_bundler_spec.rb
92
+ - spec/css_reader_spec.rb