dassets 0.7.0 → 0.8.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.
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