dassets 0.2.0 → 0.3.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.
Files changed (42) hide show
  1. data/README.md +15 -5
  2. data/lib/dassets.rb +59 -12
  3. data/lib/dassets/asset_file.rb +15 -14
  4. data/lib/dassets/cmds/cache_cmd.rb +33 -0
  5. data/lib/dassets/cmds/digest_cmd.rb +53 -0
  6. data/lib/dassets/{digests_file.rb → digests.rb} +14 -23
  7. data/lib/dassets/engine.rb +33 -0
  8. data/lib/dassets/runner.rb +10 -4
  9. data/lib/dassets/server/response.rb +1 -1
  10. data/lib/dassets/source_file.rb +71 -0
  11. data/lib/dassets/version.rb +1 -1
  12. data/test/support/app/assets/.digests +1 -0
  13. data/test/support/app/assets/file1.txt +1 -0
  14. data/test/support/app/assets/file2.txt +1 -0
  15. data/test/support/app/assets/grumpy_cat.jpg +0 -0
  16. data/test/support/app/assets/nested/a-thing.txt.useless.dumb +1 -0
  17. data/test/support/app/assets/nested/file3.txt +0 -0
  18. data/test/support/app/assets/public/nested/a-thing.txt.no-use +4 -0
  19. data/test/support/config/assets.rb +12 -1
  20. data/test/support/example.digests +3 -3
  21. data/test/support/public/nested/a-thing.txt-7413d18f2eba9c695a880aff67fde135.no-use +4 -0
  22. data/test/support/source_files/_ignored.txt +0 -0
  23. data/test/support/source_files/nested/_nested_ignored.txt +0 -0
  24. data/test/support/source_files/nested/test2.txt +0 -0
  25. data/test/support/source_files/test1.txt +0 -0
  26. data/test/system/cache_cmd_run_tests.rb +27 -0
  27. data/test/system/digest_cmd_run_tests.rb +70 -0
  28. data/test/unit/asset_file_tests.rb +11 -11
  29. data/test/unit/cmds/cache_cmd_tests.rb +33 -0
  30. data/test/unit/cmds/digest_cmd_tests.rb +23 -0
  31. data/test/unit/config_tests.rb +52 -7
  32. data/test/unit/dassets_tests.rb +59 -5
  33. data/test/unit/digests_tests.rb +79 -0
  34. data/test/unit/engine_tests.rb +59 -0
  35. data/test/unit/server/response_tests.rb +5 -5
  36. data/test/unit/source_file_tests.rb +82 -0
  37. metadata +45 -13
  38. data/lib/dassets/runner/cache_command.rb +0 -46
  39. data/lib/dassets/runner/digest_command.rb +0 -65
  40. data/test/unit/digests_file_tests.rb +0 -90
  41. data/test/unit/runner/cache_command_tests.rb +0 -62
  42. data/test/unit/runner/digest_command_tests.rb +0 -83
@@ -1,3 +1,3 @@
1
1
  module Dassets
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  file1.txt,daa05c683a4913b268653f7a7e36a5b4
2
2
  file2.txt,9bbe1047cffbb590f59e0e5aeff46ae4
3
3
  grumpy_cat.jpg,b0d1f399a916f7a25c4c0f693c619013
4
+ nested/a-thing.txt.no-use,7413d18f2eba9c695a880aff67fde135
4
5
  nested/file3.txt,d41d8cd98f00b204e9800998ecf8427e
@@ -0,0 +1 @@
1
+ file1.txt
@@ -0,0 +1 @@
1
+ file2.txt
@@ -1,7 +1,18 @@
1
1
  require 'dassets'
2
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
+
3
12
  Dassets.configure do |c|
4
13
  c.root_path File.expand_path("../..", __FILE__)
5
14
 
6
- end
15
+ c.engine 'dumb', @dumb_engine
16
+ c.engine 'useless', @useless_engine
7
17
 
18
+ end
@@ -1,3 +1,3 @@
1
- /path/to/file1,abc123
2
- /path/to/file2,123abc
3
- /path/to/file3,a1b2c3
1
+ path/to/file1,abc123
2
+ path/to/file2,123abc
3
+ path/to/file3,a1b2c3
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ require 'assert'
2
+ require 'fileutils'
3
+ require 'dassets'
4
+
5
+ module Dassets
6
+
7
+ class CacheCmdRunTests < Assert::Context
8
+ desc "the CacheCmd"
9
+ setup do
10
+ @cache_root_path = File.join(Dassets.config.root_path, 'public')
11
+ FileUtils.rm_rf(@cache_root_path)
12
+ end
13
+
14
+ should "create the cache root and write the cache files" do
15
+ assert_not_file_exists @cache_root_path.to_s
16
+ cmd = Dassets::Cmds::CacheCmd.new(@cache_root_path)
17
+ cmd.run
18
+
19
+ assert_file_exists @cache_root_path.to_s
20
+ cmd.digests.asset_files.each do |file|
21
+ assert_file_exists File.join(@cache_root_path, file.url)
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,70 @@
1
+ require 'assert'
2
+ require 'fileutils'
3
+ require 'dassets'
4
+
5
+ module Dassets
6
+
7
+ class DigestCmdRunTests < Assert::Context
8
+ desc "the DigestCmd"
9
+ setup do
10
+ Dassets.reset
11
+ Dassets.init
12
+ Dassets.digest_source_files
13
+
14
+ @addfile = 'addfile.txt'
15
+ @rmfile = 'file1.txt'
16
+ @updfile = 'file2.txt'
17
+ @addfile_path = File.join(File.join(Dassets.config.source_path, @addfile))
18
+ @rmfile_path = File.join(File.join(Dassets.config.source_path, @rmfile))
19
+ @updfile_path = File.join(File.join(Dassets.config.source_path, @updfile))
20
+
21
+ @rmfilecontents = File.read(@rmfile_path)
22
+ @updfilecontents = File.read(@updfile_path)
23
+ @orig_updfile_md5 = Dassets.digests[@updfile]
24
+
25
+ FileUtils.touch @addfile_path
26
+ FileUtils.rm @rmfile_path
27
+ File.open(@updfile_path, "w+"){ |f| f.write('an update') }
28
+ end
29
+ teardown do
30
+ File.open(@updfile_path, "w"){ |f| f.write @updfilecontents }
31
+ File.open(@rmfile_path, "w"){ |f| f.write @rmfilecontents }
32
+ FileUtils.rm @addfile_path
33
+
34
+ Dassets.reset
35
+ Dassets.init
36
+ Dassets.digest_source_files
37
+ end
38
+
39
+ should "update the digests on all source files when run with no given paths" do
40
+ # check before state
41
+ assert_equal 5, Dassets.digests.paths.size
42
+ assert_not_includes @addfile, Dassets.digests.paths
43
+ assert_includes @rmfile, Dassets.digests.paths
44
+ assert_equal @orig_updfile_md5, Dassets.digests[@updfile]
45
+
46
+ Dassets.digest_source_files
47
+
48
+ # see the add, update and removal
49
+ assert_equal 5, Dassets.digests.paths.size
50
+ assert_includes @addfile, Dassets.digests.paths
51
+ assert_not_includes @rmfile, Dassets.digests.paths
52
+ assert_not_equal @orig_updfile_md5, Dassets.digests[@updfile]
53
+ end
54
+
55
+ should "update the digests on a single source file when given its path" do
56
+ assert_equal 5, Dassets.digests.paths.size
57
+ assert_not_includes @addfile, Dassets.digests.paths
58
+
59
+ Dassets.digest_source_files([@addfile_path])
60
+
61
+ # see the add, don't change anything else
62
+ assert_equal 6, Dassets.digests.paths.size
63
+ assert_includes @addfile, Dassets.digests.paths
64
+ assert_includes @rmfile, Dassets.digests.paths
65
+ assert_equal @orig_updfile_md5, Dassets.digests[@updfile]
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -12,7 +12,7 @@ class Dassets::AssetFile
12
12
 
13
13
  should have_cmeths :from_abs_path
14
14
  should have_readers :path, :md5, :dirname, :extname, :basename
15
- should have_readers :files_path, :cache_path, :href
15
+ should have_readers :output_path, :url, :href
16
16
  should have_imeth :content, :mtime, :size, :mime_type, :exists?, :==
17
17
 
18
18
  should "know its given path and md5" do
@@ -26,21 +26,21 @@ class Dassets::AssetFile
26
26
  assert_equal 'file1', subject.basename
27
27
  end
28
28
 
29
- should "build it's files_path from the path" do
30
- assert_equal "#{Dassets.config.files_path}/file1.txt", subject.files_path
29
+ should "build it's output_path from the path" do
30
+ assert_equal "#{Dassets.config.output_path}/file1.txt", subject.output_path
31
31
 
32
32
  nested = Dassets::AssetFile.new('nested/file1.txt', 'abc123')
33
- assert_equal "#{Dassets.config.files_path}/nested/file1.txt", nested.files_path
33
+ assert_equal "#{Dassets.config.output_path}/nested/file1.txt", nested.output_path
34
34
  end
35
35
 
36
- should "build it's cache_path from the path and the md5" do
37
- assert_equal "file1-abc123.txt", subject.cache_path
36
+ should "build it's url from the path and the md5" do
37
+ assert_equal "file1-abc123.txt", subject.url
38
38
 
39
39
  nested = Dassets::AssetFile.new('nested/file1.txt', 'abc123')
40
- assert_equal "nested/file1-abc123.txt", nested.cache_path
40
+ assert_equal "nested/file1-abc123.txt", nested.url
41
41
  end
42
42
 
43
- should "build it's href from the cache path" do
43
+ should "build it's href from the url" do
44
44
  assert_equal "/file1-abc123.txt", subject.href
45
45
 
46
46
  nested = Dassets::AssetFile.new('nested/file1.txt', 'abc123')
@@ -48,7 +48,7 @@ class Dassets::AssetFile
48
48
  end
49
49
 
50
50
  should "be created from absolute file paths and have md5 computed" do
51
- abs_file_path = File.join(Dassets.config.files_path, 'file1.txt')
51
+ abs_file_path = File.join(Dassets.config.output_path, 'file1.txt')
52
52
  exp_md5 = 'daa05c683a4913b268653f7a7e36a5b4'
53
53
  file = Dassets::AssetFile.from_abs_path(abs_file_path)
54
54
 
@@ -58,8 +58,8 @@ class Dassets::AssetFile
58
58
 
59
59
  should "know it's content, mtime, size, mime_type, and if it exists" do
60
60
  assert_equal "file1.txt\n", subject.content
61
- assert_equal File.mtime(subject.files_path).httpdate, subject.mtime
62
- assert_equal File.size?(subject.files_path), subject.size
61
+ assert_equal File.mtime(subject.output_path).httpdate, subject.mtime
62
+ assert_equal File.size?(subject.output_path), subject.size
63
63
  assert_equal "text/plain", subject.mime_type
64
64
  assert subject.exists?
65
65
 
@@ -0,0 +1,33 @@
1
+ require 'assert'
2
+ require 'fileutils'
3
+ require 'dassets/cmds/cache_cmd'
4
+
5
+ class Dassets::Cmds::CacheCmd
6
+
7
+ class BaseTests < Assert::Context
8
+ desc "Dassets::Cmds::CacheCmd"
9
+ setup do
10
+ @cache_root_path = File.join(Dassets.config.root_path, 'public')
11
+ FileUtils.mkdir_p @cache_root_path
12
+ @cmd = Dassets::Cmds::CacheCmd.new(@cache_root_path)
13
+ end
14
+ subject{ @cmd }
15
+
16
+ should have_readers :cache_root_path, :digests
17
+
18
+ should "know its given cache root path" do
19
+ assert_equal @cache_root_path, subject.cache_root_path.to_s
20
+ end
21
+
22
+ should "know it's digests file" do
23
+ assert_kind_of Dassets::Digests, subject.digests
24
+ end
25
+
26
+ should "get it's asset files from the digests file" do
27
+ assert_equal 5, subject.digests.paths.size
28
+ assert_equal 5, subject.digests.asset_files.size
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'assert'
2
+ require 'dassets'
3
+ require 'dassets/cmds/digest_cmd'
4
+
5
+ class Dassets::Cmds::DigestCmd
6
+
7
+ class BaseTests < Assert::Context
8
+ desc "Dassets::Cmds::DigestCmd"
9
+ setup do
10
+ @cmd = Dassets::Cmds::DigestCmd.new(['a/path'])
11
+ end
12
+ subject{ @cmd }
13
+
14
+ should have_readers :paths
15
+ should have_instance_method :run
16
+
17
+ should "know it's paths" do
18
+ assert_equal ['a/path'], subject.paths
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -7,20 +7,65 @@ class Dassets::Config
7
7
  class BaseTests < Assert::Context
8
8
  include NsOptions::AssertMacros
9
9
  desc "Dassets::Config"
10
- subject{ Dassets::Config }
10
+ setup do
11
+ @config = Dassets::Config.new
12
+ end
13
+ subject{ @config }
11
14
 
12
- should have_option :assets_file, Pathname, :default => ENV['DASSETS_ASSETS_FILE']
13
- should have_option :root_path, Pathname, :required => true
14
- should have_options :files_path, :digests_file_path
15
+ should have_option :root_path, Pathname, :required => true
16
+ should have_option :assets_file, Pathname, :default => ENV['DASSETS_ASSETS_FILE']
17
+ should have_options :source_path, :output_path, :digests_path
18
+ should have_reader :engines
19
+ should have_imeth :source, :engine
15
20
 
16
- should "should use `apps/assets/public` as the default files path" do
21
+ should "should use `apps/assets` as the default source path" do
22
+ exp_path = Dassets.config.root_path.join("app/assets").to_s
23
+ assert_equal exp_path, subject.source_path
24
+ end
25
+
26
+ should "should use `apps/assets/public` as the default output path" do
17
27
  exp_path = Dassets.config.root_path.join("app/assets/public").to_s
18
- assert_equal exp_path, subject.files_path
28
+ assert_equal exp_path, subject.output_path
19
29
  end
20
30
 
21
31
  should "should use `app/assets/.digests` as the default digests file path" do
22
32
  exp_path = Dassets.config.root_path.join("app/assets/.digests").to_s
23
- assert_equal exp_path, subject.digests_file_path
33
+ assert_equal exp_path, subject.digests_path.to_s
34
+ end
35
+
36
+ should "set the source path and filter proc with the `sources` method" do
37
+ path = Dassets::RootPath.new 'app/asset_files'
38
+ filter = proc{ |paths| [] }
39
+
40
+ subject.source(path, &filter)
41
+ assert_equal path, subject.source_path
42
+ assert_equal filter, subject.source_filter
43
+ end
44
+
45
+ should "know its engines and return a NullEngine by default" do
46
+ assert_kind_of ::Hash, subject.engines
47
+ assert_kind_of Dassets::NullEngine, subject.engines['some']
48
+ assert_kind_of Dassets::NullEngine, subject.engines['thing']
49
+ end
50
+
51
+ should "allow registering new engines" do
52
+ empty_engine = Class.new(Dassets::Engine) do
53
+ def ext(input_ext); ''; end
54
+ def compile(input); ''; end
55
+ end
56
+
57
+ assert_kind_of Dassets::NullEngine, subject.engines['empty']
58
+ subject.engine 'empty', empty_engine, 'an' => 'opt'
59
+ assert_kind_of empty_engine, subject.engines['empty']
60
+
61
+ assert_equal({'an' => 'opt'}, subject.engines['empty'].opts)
62
+ assert_equal '', subject.engines['empty'].ext('empty')
63
+ assert_equal '', subject.engines['empty'].compile('some content')
64
+ end
65
+
66
+ should "should use `apps/assets/public` as the default files path" do
67
+ exp_path = Dassets.config.root_path.join("app/assets/public").to_s
68
+ assert_equal exp_path, subject.output_path
24
69
  end
25
70
 
26
71
  end
@@ -8,18 +8,28 @@ module Dassets
8
8
  desc "Dassets"
9
9
  subject{ Dassets }
10
10
 
11
- should have_imeths :config, :configure, :init, :digests, :[]
11
+ should have_imeths :config, :sources, :digests
12
+ should have_imeths :configure, :reset, :init, :[]
13
+ should have_imeths :digest_source_files
12
14
 
13
- should "return its `Config` class with the `config` method" do
14
- assert_same Config, subject.config
15
+ should "return a `Config` instance with the `config` method" do
16
+ assert_kind_of Config, subject.config
17
+ end
18
+
19
+ should "read the source list on init" do
20
+ subject.reset
21
+ assert_empty subject.sources
22
+
23
+ subject.init
24
+ assert_not_empty subject.sources
15
25
  end
16
26
 
17
27
  should "read/parse the digests on init" do
18
28
  subject.reset
19
- assert_empty subject.digests
29
+ assert_empty subject.digests.paths
20
30
 
21
31
  subject.init
22
- assert_not_empty subject.digests
32
+ assert_not_empty subject.digests.paths
23
33
  end
24
34
 
25
35
  should "return asset files given a their path using the index operator" do
@@ -46,4 +56,48 @@ module Dassets
46
56
 
47
57
  end
48
58
 
59
+ class SourceListTests < BaseTests
60
+ desc "source list"
61
+
62
+ should "build from the configured source path and filter proc" do
63
+ config = Dassets::Config.new
64
+ config.source_path = "source_files" # test/support/source_files
65
+ exp_list = [
66
+ 'test1.txt', '_ignored.txt', 'nested/test2.txt', 'nested/_nested_ignored.txt'
67
+ ].map{ |p| File.expand_path(p, config.source_path) }.sort
68
+
69
+ assert_equal exp_list, Dassets::SourceList.new(config)
70
+ end
71
+
72
+ should "filter out any paths in the output path" do
73
+ config = Dassets::Config.new
74
+ config.source_path = "source_files" # test/support/source_files
75
+ config.output_path = "source_files/nested"
76
+ exp_list = [
77
+ 'test1.txt', '_ignored.txt'
78
+ ].map{ |p| File.expand_path(p, config.source_path) }.sort
79
+
80
+ assert_equal exp_list, Dassets::SourceList.new(config)
81
+ end
82
+
83
+ should "run the supplied source filter on the paths" do
84
+ config = Dassets::Config.new
85
+ config.source_path = "source_files" # test/support/source_files
86
+ config.source_filter = proc do |paths|
87
+ paths.reject{ |path| File.basename(path) =~ /^_/ }
88
+ end
89
+ exp_list = [
90
+ 'test1.txt', 'nested/test2.txt'
91
+ ].map{ |p| File.expand_path(p, config.source_path) }.sort
92
+
93
+ assert_equal exp_list, Dassets::SourceList.new(config)
94
+
95
+ config.source "source_files" do |paths|
96
+ paths.reject{ |path| File.basename(path) =~ /^_/ }
97
+ end
98
+ assert_equal exp_list, Dassets::SourceList.new(config)
99
+ end
100
+
101
+ end
102
+
49
103
  end
@@ -0,0 +1,79 @@
1
+ require 'assert'
2
+ require 'fileutils'
3
+ require 'dassets/digests'
4
+ require 'dassets/asset_file'
5
+
6
+ class Dassets::Digests
7
+
8
+ class BaseTests < Assert::Context
9
+ desc "Dassets::Digests"
10
+ setup do
11
+ @file_path = File.join(Dassets.config.root_path, 'example.digests')
12
+ @digests = Dassets::Digests.new(@file_path)
13
+ end
14
+ subject{ @digests }
15
+
16
+ should have_reader :file_path
17
+ should have_imeths :[], :[]=, :delete, :clear
18
+ should have_imeths :paths, :asset_files, :asset_file, :save!
19
+
20
+ should "know its file path" do
21
+ assert_equal @file_path, subject.file_path
22
+ end
23
+
24
+ should "know its asset files" do
25
+ assert_equal subject.paths.size, subject.asset_files.size
26
+ assert_kind_of Dassets::AssetFile, subject.asset_files.first
27
+ end
28
+
29
+ should "get a specific asset file from its data" do
30
+ file = subject.asset_file('path/to/file1')
31
+
32
+ assert_kind_of Dassets::AssetFile, file
33
+ assert_equal 'path/to/file1', file.path
34
+ assert_equal subject['path/to/file1'], file.md5
35
+ end
36
+
37
+ should "read values with the index operator" do
38
+ assert_equal 'abc123', subject['path/to/file1']
39
+ end
40
+
41
+ should "write values with the index operator" do
42
+ subject['path/to/test'] = 'testytest'
43
+ assert_equal 'testytest', subject['path/to/test']
44
+ end
45
+
46
+ should "remove values with the delete method" do
47
+ assert_includes 'path/to/file1', subject.paths
48
+
49
+ subject.delete 'path/to/file1'
50
+ assert_not_includes 'path/to/file1', subject.paths
51
+ end
52
+
53
+ should "clear values with the clear method" do
54
+ assert_not_empty subject.paths
55
+ subject.clear
56
+ assert_empty subject.paths
57
+ end
58
+
59
+ end
60
+
61
+ class SaveTests < BaseTests
62
+ desc "on save"
63
+ setup do
64
+ FileUtils.mv(@file_path, "#{@file_path}.bak")
65
+ end
66
+ teardown do
67
+ FileUtils.mv("#{@file_path}.bak", @file_path)
68
+ end
69
+
70
+ should "write out the digests to the file path" do
71
+ assert_not_file_exists subject.file_path
72
+ subject.save!
73
+
74
+ assert_file_exists subject.file_path
75
+ end
76
+
77
+ end
78
+
79
+ end