assetbuild 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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