dassets 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Dassets.configure do |c|
20
20
  # (optional) tell Dassets where to store digested asset files
21
21
  # if none given, Dassets will not write any digested output
22
22
  # use this to "cache" digested assets to the public dir (for example)
23
- c.file_store '/path/to/public' # default: `NullFileStore.new`
23
+ c.file_store '/path/to/public' # default: `FileStore::NullStore.new`
24
24
 
25
25
  end
26
26
  ```
data/dassets.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_development_dependency("assert", ["~> 2.0"])
20
+ gem.add_development_dependency("assert", ["~> 2.4"])
21
21
  gem.add_development_dependency('assert-rack-test', ["~> 1.0"])
22
22
  gem.add_development_dependency("sinatra", ["~> 1.4"])
23
23
 
@@ -21,39 +21,37 @@ class Dassets::AssetFile
21
21
  end
22
22
 
23
23
  def url
24
- @url ||= begin
25
- url_basename = "#{@basename}-#{self.fingerprint}#{@extname}"
26
- File.join(@dirname, url_basename).sub(/^\.\//, '').sub(/^\//, '')
27
- end
24
+ url_basename = "#{@basename}-#{self.fingerprint}#{@extname}"
25
+ File.join(@dirname, url_basename).sub(/^\.\//, '').sub(/^\//, '')
28
26
  end
29
27
 
30
28
  def href
31
- @href ||= "/#{self.url}"
29
+ "/#{self.url}"
32
30
  end
33
31
 
34
32
  def fingerprint
35
33
  return nil if !self.exists?
36
- @fingerprint ||= @source_proxy.fingerprint
34
+ @source_proxy.fingerprint
37
35
  end
38
36
 
39
37
  def content
40
38
  return nil if !self.exists?
41
- @content ||= @source_proxy.content
39
+ @source_proxy.content
42
40
  end
43
41
 
44
42
  def mtime
45
43
  return nil if !self.exists?
46
- @mtime ||= @source_proxy.mtime.httpdate
44
+ @source_proxy.mtime.httpdate
47
45
  end
48
46
 
49
47
  def size
50
48
  return nil if !self.exists?
51
- @size ||= Rack::Utils.bytesize(self.content)
49
+ Rack::Utils.bytesize(self.content)
52
50
  end
53
51
 
54
52
  def mime_type
55
53
  return nil if !self.exists?
56
- @mime_type ||= Rack::Mime.mime_type(@extname)
54
+ Rack::Mime.mime_type(@extname)
57
55
  end
58
56
 
59
57
  def exists?
@@ -0,0 +1,45 @@
1
+ module Dassets; end
2
+ module Dassets::Cache
3
+
4
+ class MemCache
5
+ require 'thread'
6
+
7
+ # this is a thread-safe in-memory cache for use with the `SourceCache`
8
+
9
+ def initialize
10
+ @hash = {}
11
+ @write_mutex = ::Mutex.new
12
+ end
13
+
14
+ def keys
15
+ @hash.keys
16
+ end
17
+
18
+ def [](key)
19
+ @hash[key]
20
+ end
21
+
22
+ def []=(key, value)
23
+ @write_mutex.synchronize{ @hash[key] = value }
24
+ end
25
+
26
+ end
27
+
28
+ class NoCache
29
+
30
+ # This is a no-op cache object. This is the default cache in use and "turns
31
+ # off caching.
32
+
33
+ def keys
34
+ []
35
+ end
36
+
37
+ def [](key)
38
+ end
39
+
40
+ def []=(key, value)
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,39 @@
1
+ require 'pathname'
2
+ require 'ns-options'
3
+ require 'dassets/cache'
4
+ require 'dassets/file_store'
5
+ require 'dassets/source'
6
+
7
+ module Dassets
8
+
9
+ class Config
10
+ include NsOptions::Proxy
11
+
12
+ option :file_store, FileStore, :default => proc{ FileStore::NullStore.new }
13
+ option :cache, :default => proc{ Cache::NoCache.new }
14
+
15
+ attr_reader :sources, :combinations
16
+
17
+ def initialize
18
+ super
19
+ @sources = []
20
+ @combinations = Hash.new{ |h, k| [k] } # digest pass-thru if none defined
21
+ end
22
+
23
+ def source(path, &block)
24
+ @sources << Source.new(path).tap{ |s| block.call(s) if block }
25
+ end
26
+
27
+ def combination(key_digest_path, value_digest_paths)
28
+ @combinations[key_digest_path.to_s] = [*value_digest_paths]
29
+ end
30
+
31
+ def combination?(key_digest_path)
32
+ # a digest path is only considered a combination is it is not the default
33
+ # pass-thru above
34
+ @combinations[key_digest_path.to_s] != [key_digest_path]
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -1,35 +1,38 @@
1
1
  require 'thread'
2
2
 
3
- module Dassets; end
4
- class Dassets::FileStore
5
- attr_reader :root
3
+ module Dassets
6
4
 
7
- def initialize(root)
8
- @root = root
9
- @save_mutex = ::Mutex.new
10
- end
5
+ class FileStore
6
+ attr_reader :root
7
+
8
+ def initialize(root)
9
+ @root = root
10
+ @save_mutex = ::Mutex.new
11
+ end
11
12
 
12
- def save(url, &block)
13
- @save_mutex.synchronize do
14
- store_path(url).tap do |path|
15
- FileUtils.mkdir_p(File.dirname(path))
16
- File.open(path, "w"){ |f| f.write(block.call) }
13
+ def save(url, &block)
14
+ @save_mutex.synchronize do
15
+ store_path(url).tap do |path|
16
+ FileUtils.mkdir_p(File.dirname(path))
17
+ File.open(path, "w"){ |f| f.write(block.call) }
18
+ end
17
19
  end
18
20
  end
19
- end
20
21
 
21
- def store_path(url)
22
- File.join(@root, url)
23
- end
22
+ def store_path(url)
23
+ File.join(@root, url)
24
+ end
24
25
 
25
- end
26
+ class NullStore < FileStore
27
+ def initialize
28
+ super('')
29
+ end
26
30
 
27
- class Dassets::NullFileStore < Dassets::FileStore
28
- def initialize
29
- super('')
30
- end
31
+ def save(url, &block)
32
+ store_path(url) # no-op, just return the store path like the base does
33
+ end
34
+ end
31
35
 
32
- def save(url, &block)
33
- store_path(url) # no-op, just return the store path like the base does
34
36
  end
37
+
35
38
  end
@@ -47,7 +47,7 @@ module Dassets
47
47
  end
48
48
 
49
49
  def compiled
50
- @compiled ||= @ext_list.inject(read_file(@file_path)) do |content, ext|
50
+ @ext_list.inject(read_file(@file_path)) do |content, ext|
51
51
  self.source.engines[ext].compile(content)
52
52
  end
53
53
  end
@@ -89,26 +89,27 @@ module Dassets
89
89
  def initialize(digest_path, cache = nil)
90
90
  @file_path, @ext_list = '', []
91
91
  @digest_path = digest_path
92
- @source_compiled, @source_exists, @source_mtime = nil, false, nil
93
-
94
- # if the digest path is a combination, build its proxy and use relevent
95
- # properties as the source file properties
96
- if Dassets.config.combination?(@digest_path)
97
- source_proxy = SourceProxy.new(@digest_path, cache)
98
- @source_compiled = source_proxy.content
99
- @source_exists = source_proxy.exists?
100
- @source_mtime = source_proxy.mtime
92
+ @source_proxy = if Dassets.config.combination?(@digest_path)
93
+ SourceProxy.new(@digest_path, cache)
94
+ else
95
+ NullSourceProxy.new
101
96
  end
102
97
  end
103
98
 
104
- def compiled; @source_compiled; end
105
- def exists?; @source_exists; end
106
- def mtime; @source_mtime; end
99
+ def compiled; @source_proxy.content; end
100
+ def exists?; @source_proxy.exists?; end
101
+ def mtime; @source_proxy.mtime; end
107
102
 
108
103
  def ==(other_source_file)
109
104
  self.file_path == other_source_file.file_path
110
105
  end
111
106
 
107
+ class NullSourceProxy
108
+ def content; nil; end
109
+ def exists?; false; end
110
+ def mtime; nil; end
111
+ end
112
+
112
113
  end
113
114
 
114
115
  end
@@ -1,4 +1,5 @@
1
1
  require 'digest/md5'
2
+ require 'dassets/cache'
2
3
  require 'dassets/source_file'
3
4
 
4
5
  module Dassets; end
@@ -8,7 +9,7 @@ class Dassets::SourceProxy
8
9
 
9
10
  def initialize(digest_path, cache = nil)
10
11
  @digest_path = digest_path
11
- @cache = cache || NoCache.new
12
+ @cache = cache || Dassets::Cache::NoCache.new
12
13
  @source_files = get_source_files(@digest_path, @cache)
13
14
  end
14
15
 
@@ -35,11 +36,11 @@ class Dassets::SourceProxy
35
36
  private
36
37
 
37
38
  def source_content
38
- @source_content ||= @source_files.map{ |f| f.compiled }.join("\n")
39
+ @source_files.map{ |f| f.compiled }.join("\n")
39
40
  end
40
41
 
41
42
  def source_fingerprint
42
- @source_fingerprint ||= Digest::MD5.new.hexdigest(source_content)
43
+ Digest::MD5.new.hexdigest(source_content)
43
44
  end
44
45
 
45
46
  def get_source_files(digest_path, cache)
@@ -48,9 +49,4 @@ class Dassets::SourceProxy
48
49
  end
49
50
  end
50
51
 
51
- class NoCache
52
- def [](key); end
53
- def []=(key, value); end
54
- end
55
-
56
52
  end
@@ -1,3 +1,3 @@
1
1
  module Dassets
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/dassets.rb CHANGED
@@ -1,68 +1,26 @@
1
- require 'pathname'
2
- require 'set'
3
- require 'ns-options'
4
-
5
1
  require 'dassets/version'
6
- require 'dassets/file_store'
7
- require 'dassets/default_cache'
8
- require 'dassets/source'
9
2
  require 'dassets/asset_file'
10
-
11
- ENV['DASSETS_ASSETS_FILE'] ||= 'config/assets'
3
+ require 'dassets/config'
12
4
 
13
5
  module Dassets
14
6
 
15
- def self.config; @config ||= Config.new; end
7
+ def self.config; @config ||= Config.new; end
16
8
  def self.configure(&block)
17
9
  block.call(self.config)
18
10
  end
19
11
 
20
12
  def self.init
21
- begin
22
- require self.config.assets_file
23
- rescue LoadError
24
- end
13
+ @asset_files ||= {}
25
14
  end
26
15
 
27
16
  def self.[](digest_path)
28
- AssetFile.new(digest_path)
17
+ @asset_files[digest_path] ||= AssetFile.new(digest_path)
29
18
  end
30
19
 
31
20
  def self.source_list
32
21
  SourceList.new(self.config.sources)
33
22
  end
34
23
 
35
- class Config
36
- include NsOptions::Proxy
37
-
38
- option :assets_file, Pathname, :default => ENV['DASSETS_ASSETS_FILE']
39
- option :file_store, FileStore, :default => proc{ NullFileStore.new }
40
-
41
- attr_reader :sources, :combinations
42
- attr_accessor :cache
43
-
44
- def initialize
45
- super
46
- @sources = []
47
- @combinations = Hash.new{ |h, k| [k] } # digest pass-thru if none defined
48
- @cache = DefaultCache.new
49
- end
50
-
51
- def source(path, &block)
52
- @sources << Source.new(path).tap{ |s| block.call(s) if block }
53
- end
54
-
55
- def combination(key_digest_path, value_digest_paths)
56
- @combinations[key_digest_path.to_s] = [*value_digest_paths]
57
- end
58
-
59
- def combination?(key_digest_path)
60
- # a digest path is only considered a combination is it is not the default
61
- # pass-thru above
62
- @combinations[key_digest_path.to_s] != [key_digest_path]
63
- end
64
- end
65
-
66
24
  module SourceList
67
25
  def self.new(sources)
68
26
  sources.inject([]){ |list, source| list += source.files }
data/test/helper.rb CHANGED
@@ -11,6 +11,23 @@ require 'pathname'
11
11
  TEST_SUPPORT_PATH = Pathname.new(File.expand_path('../support', __FILE__))
12
12
 
13
13
  ENV['DASSETS_TEST_MODE'] = 'yes'
14
- ENV['DASSETS_ASSETS_FILE'] = 'test/support/config/assets'
14
+
15
15
  require 'dassets'
16
+
17
+ @dumb_engine = Class.new(Dassets::Engine) do
18
+ def ext(in_ext); ''; end
19
+ def compile(input); "#{input}\nDUMB"; end
20
+ end
21
+ @useless_engine = Class.new(Dassets::Engine) do
22
+ def ext(in_ext); 'no-use'; end
23
+ def compile(input); "#{input}\nUSELESS"; end
24
+ end
25
+
26
+ Dassets.configure do |c|
27
+ c.source TEST_SUPPORT_PATH.join("app/assets") do |s|
28
+ s.engine 'dumb', @dumb_engine
29
+ s.engine 'useless', @useless_engine
30
+ end
31
+ end
32
+
16
33
  Dassets.init
@@ -1,8 +1,10 @@
1
1
  require 'assert'
2
+ require 'dassets'
3
+
2
4
  require 'assert-rack-test'
3
5
  require 'fileutils'
4
- require 'test/support/app'
5
6
  require 'dassets/server'
7
+ require 'test/support/app'
6
8
 
7
9
  module Dassets
8
10
 
@@ -46,7 +48,7 @@ module Dassets
46
48
  FileUtils.rm(@url_file)
47
49
  end
48
50
  teardown do
49
- Dassets.config.file_store = NullFileStore.new
51
+ Dassets.config.file_store = FileStore::NullStore.new
50
52
  end
51
53
 
52
54
  should "digest the asset" do
@@ -1,12 +1,13 @@
1
1
  require 'assert'
2
+ require 'dassets/asset_file'
3
+
2
4
  require 'fileutils'
3
5
  require 'dassets/file_store'
4
6
  require 'dassets/source_proxy'
5
- require 'dassets/asset_file'
6
7
 
7
8
  class Dassets::AssetFile
8
9
 
9
- class BaseTests < Assert::Context
10
+ class UnitTests < Assert::Context
10
11
  desc "Dassets::AssetFile"
11
12
  setup do
12
13
  @asset_file = Dassets::AssetFile.new('file1.txt')
@@ -81,9 +82,31 @@ class Dassets::AssetFile
81
82
  assert_equal "/nested/file1-.txt", nested.href
82
83
  end
83
84
 
85
+ should "not memoize its attributes" do
86
+ url1 = subject.url
87
+ url2 = subject.url
88
+ assert_not_same url2, url1
89
+
90
+ href1 = subject.href
91
+ href2 = subject.href
92
+ assert_not_same href2, href1
93
+
94
+ fingerprint1 = subject.fingerprint
95
+ fingerprint2 = subject.fingerprint
96
+ assert_not_same fingerprint2, fingerprint1
97
+
98
+ content1 = subject.content
99
+ content2 = subject.content
100
+ assert_not_same content2, content1
101
+
102
+ mtime1 = subject.mtime
103
+ mtime2 = subject.mtime
104
+ assert_not_same mtime2, mtime1
105
+ end
106
+
84
107
  end
85
108
 
86
- class DigestTests < BaseTests
109
+ class DigestTests < UnitTests
87
110
  desc "being digested with an output path configured"
88
111
  setup do
89
112
  Dassets.config.file_store = TEST_SUPPORT_PATH.join('public').to_s
@@ -91,7 +114,7 @@ class Dassets::AssetFile
91
114
  @outfile = Dassets.config.file_store.store_path(@asset_file.url)
92
115
  end
93
116
  teardown do
94
- Dassets.config.file_store = Dassets::NullFileStore.new
117
+ Dassets.config.file_store = Dassets::FileStore::NullStore.new
95
118
  end
96
119
 
97
120
  should "return the asset file url" do
@@ -0,0 +1,53 @@
1
+ require 'assert'
2
+ require 'dassets/cache'
3
+
4
+ module Dassets::Cache
5
+
6
+ class UnitTests < Assert::Context
7
+ desc "Dassets::Cache"
8
+
9
+ should "define an in-memory cache handler" do
10
+ assert MemCache
11
+ end
12
+
13
+ should "define a no-op cache handler" do
14
+ assert NoCache
15
+ end
16
+
17
+ end
18
+
19
+ class MemCacheTests < UnitTests
20
+ desc "MemCache"
21
+ setup do
22
+ @cache = MemCache.new
23
+ end
24
+ subject{ @cache }
25
+
26
+ should have_imeths :keys, :[], :[]=
27
+
28
+ should "cache given key/value pairs in memory" do
29
+ val = []
30
+ subject['something'] = val
31
+ assert_same val, subject['something']
32
+ end
33
+
34
+ end
35
+
36
+ class NoCacheTests < UnitTests
37
+ desc "NoCache"
38
+ setup do
39
+ @cache = NoCache.new
40
+ end
41
+ subject{ @cache }
42
+
43
+ should have_imeths :keys, :[], :[]=
44
+
45
+ should "not cache given key/value pairs in memory" do
46
+ val = []
47
+ subject['something'] = val
48
+ assert_not_same val, subject['something']
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -1,23 +1,33 @@
1
1
  require 'assert'
2
+ require 'dassets/config'
3
+
2
4
  require 'ns-options/assert_macros'
3
- require 'dassets'
5
+ require 'dassets/cache'
6
+ require 'dassets/file_store'
4
7
 
5
8
  class Dassets::Config
6
9
 
7
- class BaseTests < Assert::Context
10
+ class UnitTests < Assert::Context
8
11
  include NsOptions::AssertMacros
12
+
9
13
  desc "Dassets::Config"
10
14
  setup do
11
15
  @config = Dassets::Config.new
12
16
  end
13
17
  subject{ @config }
14
18
 
15
- should have_option :assets_file, Pathname, :default => ENV['DASSETS_ASSETS_FILE']
16
- should have_options :file_store
17
-
19
+ should have_options :file_store, :cache
18
20
  should have_reader :combinations
19
21
  should have_imeth :source, :combination, :combination?
20
22
 
23
+ should "default the file store option to a null file store" do
24
+ assert_kind_of Dassets::FileStore::NullStore, subject.file_store
25
+ end
26
+
27
+ should "default the cache option to no caching" do
28
+ assert_kind_of Dassets::Cache::NoCache, subject.cache
29
+ end
30
+
21
31
  should "register new sources with the `source` method" do
22
32
  path = '/path/to/app/assets'
23
33
  filter = proc{ |paths| [] }
@@ -1,10 +1,12 @@
1
1
  require 'assert'
2
- require 'fileutils'
3
2
  require 'dassets'
4
3
 
4
+ require 'fileutils'
5
+ require 'dassets/asset_file'
6
+
5
7
  module Dassets
6
8
 
7
- class BaseTests < Assert::Context
9
+ class UnitTests < Assert::Context
8
10
  desc "Dassets"
9
11
  subject{ Dassets }
10
12
 
@@ -23,6 +25,13 @@ module Dassets
23
25
  assert_equal 'd41d8cd98f00b204e9800998ecf8427e', file.fingerprint
24
26
  end
25
27
 
28
+ should "cache asset files" do
29
+ file1 = subject['nested/file3.txt']
30
+ file2 = subject['nested/file3.txt']
31
+
32
+ assert_same file2, file1
33
+ end
34
+
26
35
  should "return an asset file that doesn't exist if digest path not found" do
27
36
  file = subject['path/not/found.txt']
28
37
  assert_not file.exists?
@@ -3,7 +3,7 @@ require 'dassets/engine'
3
3
 
4
4
  class Dassets::Engine
5
5
 
6
- class BaseTests < Assert::Context
6
+ class UnitTests < Assert::Context
7
7
  desc "the base Dassets::Engine"
8
8
  setup do
9
9
  @engine = Dassets::Engine.new
@@ -3,13 +3,48 @@ require 'dassets/file_store'
3
3
 
4
4
  class Dassets::FileStore
5
5
 
6
- class NullTests < Assert::Context
7
- desc "Dassets::NullFileStore"
8
- subject{ Dassets::NullFileStore.new }
6
+ class UnitTests < Assert::Context
7
+ desc "Dassets::FileStore"
8
+ setup do
9
+ @root = TEST_SUPPORT_PATH.join('public')
10
+ @url = 'some/url'
11
+ @url_path = @root.join(@url).to_s
12
+ FileUtils.rm_f(@url_path)
13
+
14
+ @store = Dassets::FileStore.new(@root.to_s)
15
+ end
16
+ teardown do
17
+ FileUtils.rm_f(@url_path)
18
+ end
19
+ subject{ @store }
9
20
 
10
- should have_reader :root
21
+ should have_readers :root
11
22
  should have_imeths :save, :store_path
12
23
 
24
+ should "know its root path" do
25
+ assert_equal @root.to_s, subject.root
26
+ end
27
+
28
+ should "build the store path based on a given url" do
29
+ assert_equal @url_path, subject.store_path(@url)
30
+ end
31
+
32
+ should "return write a file and return the store path on save" do
33
+ assert_not_file_exists @url_path
34
+ path = subject.save(@url){ 'some contents' }
35
+
36
+ assert_equal @url_path, path
37
+ assert_file_exists @url_path
38
+ end
39
+
40
+ end
41
+
42
+ class NullStoreTests < UnitTests
43
+ desc "NullStore"
44
+ setup do
45
+ @store = Dassets::FileStore::NullStore.new
46
+ end
47
+
13
48
  should "be a kind of FileStore" do
14
49
  assert_kind_of Dassets::FileStore, subject
15
50
  end
@@ -18,12 +53,8 @@ class Dassets::FileStore
18
53
  assert_equal '', subject.root
19
54
  end
20
55
 
21
- should "build the store path based on a given url" do
22
- assert_equal '/some/url', subject.store_path('some/url')
23
- end
24
-
25
56
  should "return the store path on save" do
26
- assert_equal '/some/url', subject.save('some/url')
57
+ assert_equal "/#{@url}", subject.save(@url)
27
58
  end
28
59
 
29
60
  end
@@ -1,9 +1,11 @@
1
1
  require 'assert'
2
2
  require 'dassets/server/request'
3
3
 
4
+ require 'dassets/asset_file'
5
+
4
6
  class Dassets::Server::Request
5
7
 
6
- class BaseTests < Assert::Context
8
+ class UnitTests < Assert::Context
7
9
  desc "Dassets::Server::Request"
8
10
  setup do
9
11
  @req = file_request('GET', '/file1-daa05c683a4913b268653f7a7e36a5b4.txt')
@@ -1,10 +1,12 @@
1
1
  require 'assert'
2
- require 'rack/utils'
3
2
  require 'dassets/server/response'
4
3
 
4
+ require 'rack/utils'
5
+ require 'dassets/asset_file'
6
+
5
7
  class Dassets::Server::Response
6
8
 
7
- class BaseTests < Assert::Context
9
+ class UnitTests < Assert::Context
8
10
  desc "Dassets::Server::Response"
9
11
  setup do
10
12
  @resp = file_response(Dassets::AssetFile.new(''))
@@ -2,6 +2,7 @@ require 'assert'
2
2
  require 'dassets/source_file'
3
3
 
4
4
  require 'dassets/asset_file'
5
+ require 'dassets/source_proxy'
5
6
 
6
7
  class Dassets::SourceFile
7
8
 
@@ -51,6 +52,12 @@ class Dassets::SourceFile
51
52
  assert_not_same subject, found
52
53
  end
53
54
 
55
+ should "not memoize its compiled source" do
56
+ compiled1 = subject.compiled
57
+ compiled2 = subject.compiled
58
+ assert_not_same compiled2, compiled1
59
+ end
60
+
54
61
  end
55
62
 
56
63
  class NullSourceTests < UnitTests
@@ -1,30 +1,37 @@
1
1
  require 'assert'
2
+ require 'dassets/source_proxy'
3
+
2
4
  require 'digest/md5'
5
+ require 'dassets/cache'
3
6
  require 'dassets/source_file'
4
7
  require 'dassets/source_proxy'
5
8
 
6
9
  class Dassets::SourceProxy
7
10
 
8
- class BaseTests < Assert::Context
11
+ class UnitTests < Assert::Context
9
12
  desc "Dassets::SourceProxy"
10
13
  setup do
11
14
  @source_proxy = Dassets::SourceProxy.new('file1.txt')
12
15
  end
13
16
  subject{ @source_proxy }
14
17
 
15
- should have_readers :digest_path, :source_files
18
+ should have_readers :digest_path, :source_files, :cache
16
19
  should have_imeths :content, :fingerprint, :key, :mtime, :exists?
17
20
 
18
21
  should "know its digest path" do
19
22
  assert_equal 'file1.txt', subject.digest_path
20
23
  end
21
24
 
22
- should "know its source file" do
25
+ should "know its source files" do
23
26
  exp_source_file = Dassets::SourceFile.find_by_digest_path('file1.txt')
24
27
  assert_equal 1, subject.source_files.size
25
28
  assert_equal exp_source_file, subject.source_files.first
26
29
  end
27
30
 
31
+ should "use a `NoCache` cache handler by default" do
32
+ assert_kind_of Dassets::Cache::NoCache, subject.cache
33
+ end
34
+
28
35
  should "exist if its source file exists" do
29
36
  assert_equal subject.source_files.first.exists?, subject.exists?
30
37
  end
@@ -49,7 +56,7 @@ class Dassets::SourceProxy
49
56
 
50
57
  end
51
58
 
52
- class CombinationTests < BaseTests
59
+ class CombinationTests < UnitTests
53
60
  desc "when the digest path is a combination to multiple source files"
54
61
  setup do
55
62
  Dassets.config.combination 'file3.txt', ['file1.txt', 'file2.txt']
@@ -89,4 +96,42 @@ class Dassets::SourceProxy
89
96
 
90
97
  end
91
98
 
99
+ class NoCacheTests < UnitTests
100
+ desc "with a `NoCache` cache handler"
101
+ setup do
102
+ @cache = Dassets::Cache::NoCache.new
103
+ @source_proxy = Dassets::SourceProxy.new('file1.txt', @cache)
104
+ end
105
+
106
+ should "not cache its source content/fingerprint" do
107
+ content1 = subject.content
108
+ content2 = subject.content
109
+ assert_not_same content2, content1
110
+
111
+ finger1 = subject.fingerprint
112
+ finger2 = subject.fingerprint
113
+ assert_not_same finger2, finger1
114
+ end
115
+
116
+ end
117
+
118
+ class MemCacheTests < UnitTests
119
+ desc "with a `MemCache` cache handler"
120
+ setup do
121
+ @cache = Dassets::Cache::MemCache.new
122
+ @source_proxy = Dassets::SourceProxy.new('file1.txt', @cache)
123
+ end
124
+
125
+ should "cache its source content/fingerprint in memory" do
126
+ content1 = subject.content
127
+ content2 = subject.content
128
+ assert_same content2, content1
129
+
130
+ finger1 = subject.fingerprint
131
+ finger2 = subject.fingerprint
132
+ assert_same finger2, finger1
133
+ end
134
+
135
+ end
136
+
92
137
  end
@@ -1,6 +1,8 @@
1
1
  require 'assert'
2
2
  require 'dassets/source'
3
3
 
4
+ require 'dassets/engine'
5
+
4
6
  class Dassets::Source
5
7
 
6
8
  class BaseTests < Assert::Context
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dassets
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 63
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 7
8
+ - 8
9
9
  - 0
10
- version: 0.7.0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kelly Redding
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2013-08-07 00:00:00 Z
19
+ date: 2013-12-05 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: assert
@@ -26,11 +26,11 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 3
29
+ hash: 11
30
30
  segments:
31
31
  - 2
32
- - 0
33
- version: "2.0"
32
+ - 4
33
+ version: "2.4"
34
34
  type: :development
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
@@ -112,7 +112,8 @@ files:
112
112
  - dassets.gemspec
113
113
  - lib/dassets.rb
114
114
  - lib/dassets/asset_file.rb
115
- - lib/dassets/default_cache.rb
115
+ - lib/dassets/cache.rb
116
+ - lib/dassets/config.rb
116
117
  - lib/dassets/engine.rb
117
118
  - lib/dassets/file_store.rb
118
119
  - lib/dassets/server.rb
@@ -130,7 +131,6 @@ files:
130
131
  - test/support/app/assets/grumpy_cat.jpg
131
132
  - test/support/app/assets/nested/a-thing.txt.useless.dumb
132
133
  - test/support/app/assets/nested/file3.txt
133
- - test/support/config/assets.rb
134
134
  - test/support/empty/.gitkeep
135
135
  - test/support/public/file1-daa05c683a4913b268653f7a7e36a5b4.txt
136
136
  - test/support/public/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt
@@ -143,9 +143,9 @@ files:
143
143
  - test/support/source_files/test1.txt
144
144
  - test/system/rack_tests.rb
145
145
  - test/unit/asset_file_tests.rb
146
+ - test/unit/cache_tests.rb
146
147
  - test/unit/config_tests.rb
147
148
  - test/unit/dassets_tests.rb
148
- - test/unit/default_cache_tests.rb
149
149
  - test/unit/engine_tests.rb
150
150
  - test/unit/file_store_tests.rb
151
151
  - test/unit/server/request_tests.rb
@@ -196,7 +196,6 @@ test_files:
196
196
  - test/support/app/assets/grumpy_cat.jpg
197
197
  - test/support/app/assets/nested/a-thing.txt.useless.dumb
198
198
  - test/support/app/assets/nested/file3.txt
199
- - test/support/config/assets.rb
200
199
  - test/support/empty/.gitkeep
201
200
  - test/support/public/file1-daa05c683a4913b268653f7a7e36a5b4.txt
202
201
  - test/support/public/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt
@@ -209,9 +208,9 @@ test_files:
209
208
  - test/support/source_files/test1.txt
210
209
  - test/system/rack_tests.rb
211
210
  - test/unit/asset_file_tests.rb
211
+ - test/unit/cache_tests.rb
212
212
  - test/unit/config_tests.rb
213
213
  - test/unit/dassets_tests.rb
214
- - test/unit/default_cache_tests.rb
215
214
  - test/unit/engine_tests.rb
216
215
  - test/unit/file_store_tests.rb
217
216
  - test/unit/server/request_tests.rb
@@ -1,29 +0,0 @@
1
- require 'thread'
2
-
3
- # this is a thread-safe in-memory cache for use with the `SourceCache` that
4
- # only caches source fingerprint keys. there are a few reasons for using this
5
- # as the "default":
6
- # * source fingerprints are accessed more frequently than contents (ie hrefs,
7
- # urls, etc) so caching them can have nice affects on performance. Plus it
8
- # seems silly to have to compile the source file everytime you want to get its
9
- # href so you can link it in.
10
- # * fingerprints have a much smaller data size so won't overly bloat memory.
11
-
12
- class Dassets::DefaultCache
13
-
14
- def initialize
15
- @hash = {}
16
- @write_mutex = ::Mutex.new
17
- end
18
-
19
- def keys; @hash.keys; end
20
- def [](key); @hash[key]; end
21
-
22
- def []=(key, value)
23
- @write_mutex.synchronize do
24
- @hash[key] = value if key =~ /-- fingerprint$/ # only write fingerprint keys
25
- end
26
- end
27
-
28
- end
29
-
@@ -1,20 +0,0 @@
1
- require 'dassets'
2
-
3
- @dumb_engine = Class.new(Dassets::Engine) do
4
- def ext(in_ext); ''; end
5
- def compile(input); "#{input}\nDUMB"; end
6
- end
7
- @useless_engine = Class.new(Dassets::Engine) do
8
- def ext(in_ext); 'no-use'; end
9
- def compile(input); "#{input}\nUSELESS"; end
10
- end
11
-
12
- Dassets.configure do |c|
13
- c.source TEST_SUPPORT_PATH.join("app/assets") do |s|
14
- s.engine 'dumb', @dumb_engine
15
- s.engine 'useless', @useless_engine
16
- end
17
-
18
- c.cache = nil # use no cache
19
-
20
- end
@@ -1,27 +0,0 @@
1
- require 'assert'
2
- require 'dassets/default_cache'
3
-
4
- class Dassets::DefaultCache
5
-
6
- class BaseTests < Assert::Context
7
- desc "Dassets::DefaultCache"
8
- setup do
9
- @cache = Dassets::DefaultCache.new
10
- end
11
- subject{ @cache }
12
-
13
- should have_imeths :keys, :[], :[]=
14
-
15
- should "only cache fingerprint keys" do
16
- subject['some val'] = 'something'
17
- assert_empty subject.keys
18
- assert_nil subject['some val']
19
-
20
- subject['a -- fingerprint'] = 'finger'
21
- assert_includes 'a -- fingerprint', subject.keys
22
- assert_equal 'finger', subject['a -- fingerprint']
23
- end
24
-
25
- end
26
-
27
- end