parcels 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -0
- data/LICENSE.txt +1 -1
- data/lib/parcels/environment.rb +52 -2
- data/lib/parcels/fortitude/assets.rb +3 -0
- data/lib/parcels/fortitude_alongside_parcel.rb +1 -1
- data/lib/parcels/fortitude_parcel.rb +15 -2
- data/lib/parcels/fragments/css_fragment.rb +5 -8
- data/lib/parcels/sprockets.rb +26 -14
- data/lib/parcels/utils/path_utils.rb +5 -2
- data/lib/parcels/version.rb +1 -1
- data/lib/parcels/widget_tree.rb +42 -7
- data/parcels.gemspec +1 -1
- data/spec/helpers/parcels_rails_helpers.rb +1 -1
- data/spec/helpers/sprockets_helpers.rb +12 -2
- data/spec/lib/spec/expected/expected_asset.rb +6 -3
- data/spec/lib/spec/expected/expected_asset_set.rb +2 -2
- data/spec/rails/basic_rails_spec.rb +11 -0
- data/spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module.rb +5 -0
- data/spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module_test.rb +13 -0
- data/spec/system/ad_hoc_development_mode_spec.rb +80 -0
- data/spec/system/alongside_file_spec.rb +3 -1
- data/spec/system/class_from_file_spec.rb +60 -0
- data/spec/system/workaround_directories_spec.rb +81 -0
- metadata +16 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8c86251a8065212ca19858c38857005a7871457
|
4
|
+
data.tar.gz: 9be314a2db597e039c54dd4c4365e649e345fce5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0507164165fabbce70addd13598209794d45bbfe414870db3cda85e8766de0edeca1597f973170b55444979443bd941823a00979396b3c5c7e8d02398d88be5b
|
7
|
+
data.tar.gz: 89b09a7873d8ebbf440aa06a8673bc7ddc66dd7e42975a0d72d3adf963cfddc649d252eef73691b595e25f1aa6d94da9392c5011ff222e724b506342eb43d54d
|
data/CHANGES.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# Parcels Releases
|
2
|
+
|
3
|
+
## 0.0.2, 21 January 2015
|
4
|
+
|
5
|
+
* Fixed an issue where having a `.rb` file in your `views` directory that didn't define a widget class, but rather a
|
6
|
+
module (presumably a "helper-like" module of view methods), would cause asset compilation to fail.
|
7
|
+
* Improved compatibility with non-Rails build environments (_e.g._, that used by
|
8
|
+
[Middleman](http://middlemanapp.com/)).
|
data/LICENSE.txt
CHANGED
data/lib/parcels/environment.rb
CHANGED
@@ -9,6 +9,8 @@ module Parcels
|
|
9
9
|
def initialize(sprockets_environment)
|
10
10
|
@sprockets_environment = sprockets_environment
|
11
11
|
@widget_trees = [ ]
|
12
|
+
@workaround_directories_for_widget_trees = { }
|
13
|
+
@workaround_directories_root = nil
|
12
14
|
|
13
15
|
register_engines!
|
14
16
|
end
|
@@ -30,8 +32,15 @@ module Parcels
|
|
30
32
|
widget_tree.add_workaround_directory_to_sprockets!(sprockets_environment)
|
31
33
|
end
|
32
34
|
|
33
|
-
def widget_class_from_file(
|
34
|
-
|
35
|
+
def widget_class_from_file(full_path)
|
36
|
+
widget_trees.each do |widget_tree|
|
37
|
+
if (removed = widget_tree.remove_workaround_directory_from(full_path))
|
38
|
+
full_path = removed
|
39
|
+
break
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
::Fortitude::Widget.widget_class_from_file(full_path, :root_dirs => widget_trees.map(&:widget_naming_root_dirs).flatten.uniq)
|
35
44
|
end
|
36
45
|
|
37
46
|
def create_and_add_all_workaround_directories!
|
@@ -41,12 +50,53 @@ module Parcels
|
|
41
50
|
end
|
42
51
|
|
43
52
|
def add_all_widgets_to!(sprockets_context, set_names)
|
53
|
+
if widget_trees.length == 0
|
54
|
+
raise %{Error: You have not defined any widget trees -- directories containing Fortitude widgets.
|
55
|
+
You must call #add_widget_tree! on the Parcels environment, which usually is accessible
|
56
|
+
as #parcels from your Sprockets environment.}
|
57
|
+
end
|
58
|
+
|
44
59
|
widget_trees.each { |wt| wt.add_all_widgets_to_sprockets_context!(sprockets_context, set_names) }
|
45
60
|
end
|
46
61
|
|
62
|
+
def workaround_directory_root_for_widget_tree(widget_tree)
|
63
|
+
@workaround_directories_for_widget_trees[widget_tree] ||= begin
|
64
|
+
if @workaround_directories_root
|
65
|
+
File.join(@workaround_directories_root, workaround_directory_name_for(widget_tree))
|
66
|
+
else
|
67
|
+
File.join(widget_tree.root, PARCELS_WORKAROUND_DIRECTORY_NAME)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def workaround_directories_root
|
73
|
+
@workaround_directories_root
|
74
|
+
end
|
75
|
+
|
76
|
+
def workaround_directories_root=(new_root)
|
77
|
+
new_root = File.expand_path(new_root)
|
78
|
+
|
79
|
+
if @workaround_directories_for_widget_trees.size > 0 && @workaround_directories_root != new_root
|
80
|
+
raise "You can't set the workaround directories root to:
|
81
|
+
#{new_root}
|
82
|
+
...it's already set to:
|
83
|
+
#{@workaround_directories_root}"
|
84
|
+
end
|
85
|
+
|
86
|
+
@workaround_directories_root = new_root
|
87
|
+
end
|
88
|
+
|
47
89
|
private
|
48
90
|
attr_reader :widget_trees
|
49
91
|
|
92
|
+
PARCELS_WORKAROUND_DIRECTORY_NAME = ".parcels_sprockets_workaround".freeze
|
93
|
+
|
94
|
+
def workaround_directory_name_for(widget_tree)
|
95
|
+
require 'digest/md5'
|
96
|
+
digest = Digest::MD5.hexdigest(widget_tree.root).strip
|
97
|
+
"#{PARCELS_WORKAROUND_DIRECTORY_NAME}_#{digest}"
|
98
|
+
end
|
99
|
+
|
50
100
|
def register_engines!
|
51
101
|
@engines_registered ||= begin
|
52
102
|
if ::Parcels.fortitude_available?
|
@@ -145,6 +145,9 @@ you may want to enable Parcels on any of its Fortitude superclasses, which are:
|
|
145
145
|
end
|
146
146
|
|
147
147
|
@_parcels_inline_css_fragments ||= [ ]
|
148
|
+
@_parcels_inline_css_fragments.delete_if do |fragment|
|
149
|
+
fragment.file == caller_file && fragment.line >= caller_line
|
150
|
+
end
|
148
151
|
@_parcels_inline_css_fragments += css_strings.map do |css_string|
|
149
152
|
::Parcels::Fragments::CssFragment.new(css_string, self, caller_file, caller_line, _parcels_css_options.merge(options))
|
150
153
|
end
|
@@ -26,7 +26,7 @@ module Parcels
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def usable?
|
29
|
-
|
29
|
+
!! widget_class
|
30
30
|
end
|
31
31
|
|
32
32
|
def included_in_any_set?(set_names)
|
@@ -96,7 +96,20 @@ module Parcels
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def widget_class
|
99
|
-
@widget_class ||=
|
99
|
+
@widget_class ||= begin
|
100
|
+
if widget_class_full_path
|
101
|
+
begin
|
102
|
+
::Fortitude::Widget.widget_class_from_file(widget_class_full_path,
|
103
|
+
:root_dirs => widget_tree.widget_naming_root_dirs)
|
104
|
+
rescue ::Fortitude::Widget::Files::CannotDetermineWidgetClassNameError => cdwcne
|
105
|
+
raise unless cdwcne.resulting_objects.detect { |o| o.kind_of?(Module) }
|
106
|
+
:none
|
107
|
+
end
|
108
|
+
else
|
109
|
+
:none
|
110
|
+
end
|
111
|
+
end
|
112
|
+
@widget_class unless @widget_class == :none
|
100
113
|
end
|
101
114
|
end
|
102
115
|
end
|
@@ -8,6 +8,8 @@ module Parcels
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
attr_reader :file, :line
|
12
|
+
|
11
13
|
def initialize(css_string, source, file, line, options)
|
12
14
|
options.assert_valid_keys(:engines, :wrap, :prefix)
|
13
15
|
|
@@ -51,7 +53,7 @@ module Parcels
|
|
51
53
|
end
|
52
54
|
|
53
55
|
private
|
54
|
-
attr_reader :css_string, :source, :options
|
56
|
+
attr_reader :css_string, :source, :options
|
55
57
|
|
56
58
|
def header_comment
|
57
59
|
out = "/* From '#{file}'"
|
@@ -91,13 +93,8 @@ module Parcels
|
|
91
93
|
result = data
|
92
94
|
|
93
95
|
processors.each do |processor|
|
94
|
-
|
95
|
-
|
96
|
-
args = [ file, 1, { :load_paths => context.environment.paths } ]
|
97
|
-
end
|
98
|
-
|
99
|
-
template = processor.new(*args) { result }
|
100
|
-
result = template.render(context, {})
|
96
|
+
template = processor.new(file, 1, { :load_paths => context.environment.paths, :filename => file }) { result }
|
97
|
+
result = template.render(context, { :filename => file })
|
101
98
|
end
|
102
99
|
|
103
100
|
result
|
data/lib/parcels/sprockets.rb
CHANGED
@@ -9,10 +9,6 @@ module Parcels
|
|
9
9
|
@sprockets_version_components ||= ::Sprockets::VERSION.split(".").map { |x| x.to_i }
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.requires_explicit_load_paths_for_css_template?
|
13
|
-
sprockets_version_components[0] <= 2 && sprockets_version_components[1] < 11
|
14
|
-
end
|
15
|
-
|
16
12
|
def self.requires_fix_for_protected_methods_on_directive_processor?
|
17
13
|
RUBY_VERSION =~ /^2/ && sprockets_version_components[0] <= 2 && sprockets_version_components[1] < 11
|
18
14
|
end
|
@@ -95,7 +91,7 @@ if static_compiler_class
|
|
95
91
|
end
|
96
92
|
|
97
93
|
def each_logical_path(*args, &block)
|
98
|
-
@env.each_logical_path do |logical_path|
|
94
|
+
@env.each_logical_path(*args) do |logical_path|
|
99
95
|
unless ::Parcels.is_fortitude_logical_path?(logical_path)
|
100
96
|
block.call(logical_path)
|
101
97
|
end
|
@@ -110,27 +106,42 @@ if static_compiler_class
|
|
110
106
|
|
111
107
|
static_compiler_class.class_eval do
|
112
108
|
def env
|
113
|
-
|
109
|
+
::Parcels::Sprockets::StaticCompilerEnvProxy.new(@env)
|
114
110
|
end
|
115
111
|
end
|
116
112
|
end
|
117
113
|
end
|
118
114
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
115
|
+
[ 'sass/rails/importer', 'sprockets/sass/importer' ].each do |filename|
|
116
|
+
begin
|
117
|
+
require filename
|
118
|
+
rescue LoadError => le
|
119
|
+
# oh, well
|
120
|
+
end
|
123
121
|
end
|
124
122
|
|
125
|
-
[ '::Sprockets::SassImporter', '::Sass::Rails::Importer' ].each do |class_name|
|
123
|
+
[ '::Sprockets::SassImporter', '::Sass::Rails::Importer', '::Sprockets::Sass::Importer' ].each do |class_name|
|
126
124
|
klass = class_name.constantize rescue nil
|
127
125
|
|
128
126
|
if klass
|
129
127
|
klass.class_eval do
|
130
128
|
if defined?(klass::GLOB)
|
131
129
|
def find_relative_with_parcels(name, base, options)
|
132
|
-
|
133
|
-
|
130
|
+
sprockets_context = (options[:custom] || { })[:sprockets_context]
|
131
|
+
sprockets_context ||= context if respond_to?(:context)
|
132
|
+
unless sprockets_context
|
133
|
+
raise "Unable to find the Sprockets context here; it was neither in options, nor do we have it in the class"
|
134
|
+
end
|
135
|
+
|
136
|
+
parcels = sprockets_context.environment.parcels
|
137
|
+
expanded_locations_to_search = sprockets_context.environment.paths + [ File.dirname(base) ]
|
138
|
+
expanded_locations_to_search = expanded_locations_to_search.map do |location|
|
139
|
+
if location.kind_of?(::Pathname)
|
140
|
+
location
|
141
|
+
else
|
142
|
+
::Pathname.new(location.to_s)
|
143
|
+
end
|
144
|
+
end
|
134
145
|
|
135
146
|
if name =~ self.class.const_get(:GLOB) && parcels.is_underneath_root?(base)
|
136
147
|
paths_to_search = expanded_locations_to_search
|
@@ -143,7 +154,8 @@ end
|
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
146
|
-
|
157
|
+
load_paths = (options[:load_paths] || [ ]) + expanded_locations_to_search
|
158
|
+
return find_relative_without_parcels(name, base, options.merge(:load_paths => load_paths))
|
147
159
|
end
|
148
160
|
|
149
161
|
alias_method_chain :find_relative, :parcels
|
@@ -3,6 +3,11 @@ module Parcels
|
|
3
3
|
module PathUtils
|
4
4
|
class << self
|
5
5
|
def path_under(path, under_what)
|
6
|
+
maybe_path_under(path, under_what) ||
|
7
|
+
raise(Errno::ENOENT, %{Path #{path.inspect} is not underneath directory #{under_what.inspect}.})
|
8
|
+
end
|
9
|
+
|
10
|
+
def maybe_path_under(path, under_what)
|
6
11
|
path = path.to_s.strip
|
7
12
|
under_what = under_what.to_s.strip
|
8
13
|
|
@@ -10,8 +15,6 @@ module Parcels
|
|
10
15
|
path[under_what.length..under_what.length] == File::SEPARATOR
|
11
16
|
|
12
17
|
path[(under_what.length + 1)..-1]
|
13
|
-
else
|
14
|
-
raise Errno::ENOENT, %{Path #{path.inspect} is not underneath directory #{under_what.inspect}.}
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
data/lib/parcels/version.rb
CHANGED
data/lib/parcels/widget_tree.rb
CHANGED
@@ -4,6 +4,8 @@ require 'parcels/fortitude_inline_parcel'
|
|
4
4
|
require 'parcels/fortitude_alongside_parcel'
|
5
5
|
require 'parcels/dependency_parcel_list'
|
6
6
|
|
7
|
+
require 'pathname'
|
8
|
+
|
7
9
|
require 'find'
|
8
10
|
|
9
11
|
module Parcels
|
@@ -17,11 +19,14 @@ module Parcels
|
|
17
19
|
@sprockets_environments_added_to = { }
|
18
20
|
end
|
19
21
|
|
22
|
+
def widget_naming_root_dirs
|
23
|
+
@widget_naming_root_dirs ||= [ root, File.dirname(root) ]
|
24
|
+
end
|
25
|
+
|
20
26
|
def add_workaround_directory_to_sprockets!(sprockets_environment)
|
21
27
|
return if (! root_exists?)
|
22
28
|
|
23
29
|
@sprockets_environments_added_to[sprockets_environment] ||= begin
|
24
|
-
ensure_workaround_directory_is_set_up!
|
25
30
|
sprockets_environment.prepend_path(workaround_directory)
|
26
31
|
true
|
27
32
|
end
|
@@ -31,6 +36,26 @@ module Parcels
|
|
31
36
|
::Parcels::Utils::PathUtils.path_under(full_path, root)
|
32
37
|
end
|
33
38
|
|
39
|
+
def remove_workaround_directory_from(full_path)
|
40
|
+
if (path_under_workaround = ::Parcels::Utils::PathUtils.maybe_path_under(full_path, workaround_directory))
|
41
|
+
if (separator_index = path_under_workaround.index(File::SEPARATOR))
|
42
|
+
if (separator_index > 0 && separator_index < (path_under_workaround.length - 1))
|
43
|
+
link_name = path_under_workaround[0..(separator_index - 1)]
|
44
|
+
after_link = path_under_workaround[(separator_index + 1)..-1]
|
45
|
+
|
46
|
+
if File.symlink?(File.join(workaround_directory, link_name))
|
47
|
+
link_value = File.readlink(File.join(workaround_directory, link_name))
|
48
|
+
resolved_link = File.expand_path(File.join(workaround_directory, link_value))
|
49
|
+
final_path = File.join(resolved_link, after_link)
|
50
|
+
return final_path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
34
59
|
def add_all_widgets_to_sprockets_context!(sprockets_context, set_names)
|
35
60
|
return unless root_exists?
|
36
61
|
sprockets_context.depend_on(root)
|
@@ -47,7 +72,13 @@ module Parcels
|
|
47
72
|
extension = File.extname(full_path).strip.downcase
|
48
73
|
if (klass = EXTENSION_TO_PARCEL_CLASS_MAP[extension])
|
49
74
|
parcel = klass.new(self, full_path)
|
50
|
-
|
75
|
+
if parcel.usable? && parcel.included_in_any_set?(set_names)
|
76
|
+
if all_parcels.length == 0
|
77
|
+
ensure_workaround_directory_is_set_up!
|
78
|
+
end
|
79
|
+
|
80
|
+
all_parcels << parcel
|
81
|
+
end
|
51
82
|
end
|
52
83
|
end
|
53
84
|
|
@@ -66,8 +97,6 @@ module Parcels
|
|
66
97
|
|
67
98
|
ALL_EXTENSIONS = EXTENSION_TO_PARCEL_CLASS_MAP.keys.dup.freeze
|
68
99
|
|
69
|
-
PARCELS_WORKAROUND_DIRECTORY_NAME = ".parcels_sprockets_workaround".freeze
|
70
|
-
|
71
100
|
PARCELS_LOGICAL_PATH_PREFIXES = EXTENSION_TO_PARCEL_CLASS_MAP.values.map { |k| k.logical_path_prefix }
|
72
101
|
|
73
102
|
def root_exists?
|
@@ -75,7 +104,7 @@ module Parcels
|
|
75
104
|
end
|
76
105
|
|
77
106
|
def workaround_directory
|
78
|
-
@workaround_directory ||=
|
107
|
+
@workaround_directory ||= parcels_environment.workaround_directory_root_for_widget_tree(self)
|
79
108
|
end
|
80
109
|
|
81
110
|
def ensure_workaround_directory_is_set_up!
|
@@ -127,7 +156,7 @@ However, this directory currently contains other file(s) that we weren't expecti
|
|
127
156
|
if File.symlink?(symlink)
|
128
157
|
contents = File.readlink(symlink)
|
129
158
|
|
130
|
-
if contents ==
|
159
|
+
if contents == symlink_target
|
131
160
|
# ok, great
|
132
161
|
else
|
133
162
|
File.delete(symlink)
|
@@ -151,8 +180,14 @@ and try again.}
|
|
151
180
|
|
152
181
|
def create_symlink!(prefix)
|
153
182
|
Dir.chdir(workaround_directory) do
|
154
|
-
FileUtils.ln_s(
|
183
|
+
FileUtils.ln_s(symlink_target, prefix)
|
155
184
|
end
|
156
185
|
end
|
186
|
+
|
187
|
+
def symlink_target
|
188
|
+
workaround_dir_path = Pathname.new(workaround_directory).realpath
|
189
|
+
root_path = Pathname.new(root).realpath
|
190
|
+
root_path.relative_path_from(workaround_dir_path).to_s
|
191
|
+
end
|
157
192
|
end
|
158
193
|
end
|
data/parcels.gemspec
CHANGED
@@ -44,5 +44,5 @@ Gem::Specification.new do |spec|
|
|
44
44
|
|
45
45
|
spec.add_development_dependency "oop_rails_server", "~> 0", ">= 0.0.5"
|
46
46
|
spec.add_development_dependency "css_parser"
|
47
|
-
spec.add_development_dependency "fortitude", ">= 0.9.
|
47
|
+
spec.add_development_dependency "fortitude", ">= 0.9.2"
|
48
48
|
end
|
@@ -3,9 +3,13 @@ module SprocketsHelpers
|
|
3
3
|
::Sprockets::Environment.new(*args)
|
4
4
|
end
|
5
5
|
|
6
|
+
def reset_sprockets_env!
|
7
|
+
per_example_data[:sprockets_env] = nil
|
8
|
+
end
|
9
|
+
|
6
10
|
def sprockets_env(*args, &block)
|
7
11
|
out = if args.length > 0 || block
|
8
|
-
raise "Duplicate creation of sprockets_env? #{args.inspect}" if
|
12
|
+
raise "Duplicate creation of sprockets_env? #{args.inspect}" if per_example_data[:sprockets_env]
|
9
13
|
args = [ this_example_root ] if args.length == 0
|
10
14
|
per_example_data[:sprockets_env] = new_sprockets_env(*args)
|
11
15
|
block.call(per_example_data[:sprockets_env]) if block
|
@@ -17,7 +21,13 @@ module SprocketsHelpers
|
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
|
-
|
24
|
+
default_widget_trees_to_add_to_sprockets.each do |widget_tree_root|
|
25
|
+
out.parcels.add_widget_tree!(widget_tree_root)
|
26
|
+
end
|
21
27
|
out
|
22
28
|
end
|
29
|
+
|
30
|
+
def default_widget_trees_to_add_to_sprockets
|
31
|
+
[ File.join(this_example_root, 'views') ]
|
32
|
+
end
|
23
33
|
end
|
@@ -5,11 +5,14 @@ require 'spec/expected/base_expected_asset'
|
|
5
5
|
module Spec
|
6
6
|
module Expected
|
7
7
|
class ExpectedAsset < BaseExpectedAsset
|
8
|
-
def initialize(root_directory, expected_subpath, &block)
|
8
|
+
def initialize(root_directory, expected_subpath, options = { }, &block)
|
9
9
|
super(root_directory, expected_subpath)
|
10
10
|
|
11
11
|
@expected_rules = { }
|
12
12
|
@allow_extra_rules = false
|
13
|
+
@options = options
|
14
|
+
|
15
|
+
options.assert_valid_keys(:sequencing)
|
13
16
|
|
14
17
|
instance_eval(&block) if block
|
15
18
|
end
|
@@ -52,7 +55,7 @@ module Spec
|
|
52
55
|
message << "\n\n #{remaining_asset}:\n #{remaining_asset.source}\n"
|
53
56
|
end
|
54
57
|
raise message
|
55
|
-
elsif matching_remaining_assets.length == 1
|
58
|
+
elsif matching_remaining_assets.length == 1 || options[:sequencing]
|
56
59
|
matching_remaining_asset = matching_remaining_assets.first
|
57
60
|
|
58
61
|
unless asset_matches?(matching_remaining_asset)
|
@@ -79,7 +82,7 @@ module Spec
|
|
79
82
|
end
|
80
83
|
|
81
84
|
private
|
82
|
-
attr_reader :expected_rules
|
85
|
+
attr_reader :expected_rules, :options
|
83
86
|
|
84
87
|
def extra_rules_allowed?
|
85
88
|
!! @allow_extra_rules
|
@@ -12,8 +12,8 @@ module Spec
|
|
12
12
|
instance_eval(&block) if block
|
13
13
|
end
|
14
14
|
|
15
|
-
def asset(subpath, &block)
|
16
|
-
expected_asset = Spec::Expected::ExpectedAsset.new(root_directory, subpath, &block)
|
15
|
+
def asset(subpath, options = { }, &block)
|
16
|
+
expected_asset = Spec::Expected::ExpectedAsset.new(root_directory, subpath, options, &block)
|
17
17
|
@expected_assets << expected_asset
|
18
18
|
end
|
19
19
|
|
@@ -99,4 +99,15 @@ describe "Parcels Rails basic support", :type => :rails do
|
|
99
99
|
allow_additional_assets!
|
100
100
|
end)
|
101
101
|
end
|
102
|
+
|
103
|
+
it "should allow putting a .rb file in views/ that is just a module (~ helpers)" do
|
104
|
+
compiled_rails_asset('application.css').should_match(rails_assets do
|
105
|
+
asset 'views/basic_rails_spec/helpers_module_test.rb' do
|
106
|
+
expect_wrapped_rule :p, 'color: green'
|
107
|
+
end
|
108
|
+
allow_additional_assets!
|
109
|
+
end)
|
110
|
+
|
111
|
+
expect_match("helpers_module_test", /and it is this is my_helper\! tada\!/)
|
112
|
+
end
|
102
113
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
describe "Parcels ad-hoc development mode support", :type => :system do
|
2
|
+
# Rails' development mode (which is really just ActiveSupport's class-unloading support) does the right thing:
|
3
|
+
# it actually completely unloads every class after each request cycle, removing the old class definition from memory
|
4
|
+
# (well, modulo GC, but you get the idea). This means that if you remove or change CSS definitions in a widget class,
|
5
|
+
# they will genuinely be gone/changed on the next iteration, and Parcels will behave correctly.
|
6
|
+
#
|
7
|
+
# Some programs, however -- Middleman is where I discovered this issue -- simply re-evaluate templates in development
|
8
|
+
# mode. For "normal" templates (e.g., ERb, HAML, whatever), this works just fine. But, with Parcels, this can be an
|
9
|
+
# issue: the widget class definition itself just gets re-processed, and, if you've removed CSS from the class or
|
10
|
+
# changed that CSS, the class will now have both the new *and* the old definitions around. This causes really
|
11
|
+
# frustrating chaos as your changes seem to sometimes, but not always, get picked up, depending on whether the new
|
12
|
+
# CSS actually overrides the old or depends on the old not being present (like removing a CSS selector, etc.).
|
13
|
+
#
|
14
|
+
# Unfortunately, due to the way Ruby classes work, there's no one "right way" around this issue: Ruby doesn't have
|
15
|
+
# any kind of callback saying "class X is getting defined", because re-opening classes means that there's really no
|
16
|
+
# objective way of deciding when that's true. Instead, we check for declarations of CSS on a widget class where the
|
17
|
+
# line number is equal to, or before, the line numbers of other CSS declarations, and remove those other declarations
|
18
|
+
# when this happens.
|
19
|
+
#
|
20
|
+
# This doesn't catch every single case -- if you simultaneously change CSS and add one or more lines above the .css
|
21
|
+
# call in a class, for example, it will be missed -- but it catches the vast majority of cases, and is uniformly an
|
22
|
+
# improvement to the system.
|
23
|
+
#
|
24
|
+
# This is a test to make sure that works.
|
25
|
+
context "with a widget class that gets changed" do
|
26
|
+
before :each do
|
27
|
+
files {
|
28
|
+
file 'assets/basic.css', %{
|
29
|
+
//= require_parcels
|
30
|
+
}
|
31
|
+
|
32
|
+
widget 'views/my_widget' do
|
33
|
+
css %{
|
34
|
+
p { color: red; }
|
35
|
+
}
|
36
|
+
css %{
|
37
|
+
span { color: green; }
|
38
|
+
}
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should handle the case where the CSS changes" do
|
44
|
+
compiled_sprockets_asset('basic').should_match(file_assets do
|
45
|
+
asset 'views/my_widget.rb', :sequencing => true do
|
46
|
+
expect_wrapped_rule :p, 'color: red'
|
47
|
+
end
|
48
|
+
|
49
|
+
asset 'views/my_widget.rb', :sequencing => true do
|
50
|
+
expect_wrapped_rule :span, 'color: green'
|
51
|
+
end
|
52
|
+
end)
|
53
|
+
|
54
|
+
widget_path = File.join(this_example_root, 'views', 'my_widget.rb')
|
55
|
+
expect(File.exist?(widget_path)).to be
|
56
|
+
|
57
|
+
File.open(widget_path, 'w') do |f|
|
58
|
+
f << <<-EOS
|
59
|
+
class Views::MyWidget < ::Spec::Fixtures::WidgetBase
|
60
|
+
css %{
|
61
|
+
p { color: yellow; }
|
62
|
+
}
|
63
|
+
end
|
64
|
+
EOS
|
65
|
+
end
|
66
|
+
|
67
|
+
old_sprockets_env = sprockets_env
|
68
|
+
reset_sprockets_env!
|
69
|
+
|
70
|
+
load(widget_path)
|
71
|
+
expect(sprockets_env.object_id).not_to eq(old_sprockets_env.object_id)
|
72
|
+
|
73
|
+
compiled_sprockets_asset('basic').should_match(file_assets do
|
74
|
+
asset 'views/my_widget.rb' do
|
75
|
+
expect_wrapped_rule :p, 'color: yellow'
|
76
|
+
end
|
77
|
+
end)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -161,10 +161,12 @@ describe "Parcels alongside files", :type => :system do
|
|
161
161
|
}
|
162
162
|
}
|
163
163
|
|
164
|
+
compiled_sprockets_asset('basic').source # to make sure workaround directories get added
|
165
|
+
|
164
166
|
ter = this_example_root
|
165
167
|
asset = compiled_sprockets_asset('one')
|
166
168
|
asset.should_match(file_assets do
|
167
|
-
asset 'views
|
169
|
+
asset 'views/my_widget.pcss' do
|
168
170
|
expect_rule ".parcels_class__views__my_widget p", 'color: red'
|
169
171
|
end
|
170
172
|
end)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
describe "Parcels determining classes from files", :type => :system do
|
2
|
+
context "with a widget with a non-guessable class name, but at the right point in its path" do
|
3
|
+
before :each do
|
4
|
+
files {
|
5
|
+
file 'assets/basic.css', %{
|
6
|
+
//= require_parcels
|
7
|
+
}
|
8
|
+
|
9
|
+
file 'views/foo/bar/baz.rb', %{
|
10
|
+
path = [ "Vie", "oo", "Ba", "az" ]
|
11
|
+
path[0] = path[0] + "ws"
|
12
|
+
path[1] = "F" + path[1]
|
13
|
+
path[2] = path[2] + "r"
|
14
|
+
path[3] = "B" + path[3]
|
15
|
+
|
16
|
+
(0..2).each do |index|
|
17
|
+
module_name = path[0..index].join("::")
|
18
|
+
eval("module \#{module_name}; end")
|
19
|
+
end
|
20
|
+
|
21
|
+
class_name = path.join("::")
|
22
|
+
|
23
|
+
klass = Class.new(::Spec::Fixtures::WidgetBase) do
|
24
|
+
css 'p { color: red; }'
|
25
|
+
|
26
|
+
def content
|
27
|
+
p 'hello!'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
mod = eval(path[0..-2].join("::"))
|
32
|
+
mod.const_set(path[-1], klass)
|
33
|
+
}
|
34
|
+
|
35
|
+
# eval("class \#{class_name} < ::Spec::Fixtures::WidgetBase; css 'p { color: red; }'; def content; p 'hello!'; end; end")
|
36
|
+
|
37
|
+
file 'views/foo/bar/baz.pcss', %{
|
38
|
+
div { color: blue; }
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to aggregate the CSS correctly still" do
|
44
|
+
compiled_sprockets_asset('basic').should_match(file_assets do
|
45
|
+
asset 'views/foo/bar/baz.rb' do
|
46
|
+
expect_wrapped_rule :p, 'color: red'
|
47
|
+
end
|
48
|
+
|
49
|
+
asset 'views/foo/bar/baz.pcss' do
|
50
|
+
expect_wrapped_rule :div, 'color: blue'
|
51
|
+
end
|
52
|
+
end)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should apply the correct autogenerated class to the widget" do
|
56
|
+
doc = render_file_asset('views/foo/bar/baz')
|
57
|
+
expect(classes_from(doc, 'p')).to eq([ expected_file_asset('views/foo/bar/baz.rb').parcels_wrapping_class ])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
describe "Parcels workaround directories", :type => :system do
|
2
|
+
context "with a simple widget" do
|
3
|
+
before :each do
|
4
|
+
files {
|
5
|
+
file 'assets/basic.css', %{
|
6
|
+
//= require_parcels
|
7
|
+
}
|
8
|
+
|
9
|
+
widget 'views/my_widget' do
|
10
|
+
css %{
|
11
|
+
p { color: red; }
|
12
|
+
}
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def all_workaround_directories_in(base_dir)
|
18
|
+
out = [ ]
|
19
|
+
Find.find(base_dir) do |file|
|
20
|
+
out << file if File.basename(file) =~ /^#{Regexp.escape(::Parcels::Environment::PARCELS_WORKAROUND_DIRECTORY_NAME)}/
|
21
|
+
end
|
22
|
+
out
|
23
|
+
end
|
24
|
+
|
25
|
+
def ensure_asset_compiles!
|
26
|
+
compiled_sprockets_asset('basic').should_match(file_assets do
|
27
|
+
asset 'views/my_widget.rb' do
|
28
|
+
expect_wrapped_rule :p, 'color: red'
|
29
|
+
end
|
30
|
+
end)
|
31
|
+
end
|
32
|
+
|
33
|
+
def default_widget_trees_to_add_to_sprockets
|
34
|
+
[ ]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should, by default, put workaround directories inside the widget-tree root" do
|
38
|
+
sprockets_env.parcels.add_widget_tree!(File.join(this_example_root, 'views'))
|
39
|
+
ensure_asset_compiles!
|
40
|
+
expect(all_workaround_directories_in(this_example_root)).to eq([
|
41
|
+
File.join(this_example_root, "views/#{::Parcels::Environment::PARCELS_WORKAROUND_DIRECTORY_NAME}")
|
42
|
+
])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should put workaround directories elsewhere if you tell it to" do
|
46
|
+
require 'tmpdir'
|
47
|
+
test_dir = Dir.mktmpdir do |tempdir|
|
48
|
+
sprockets_env.parcels.workaround_directories_root = File.join(tempdir, 'foo', 'bar')
|
49
|
+
sprockets_env.parcels.add_widget_tree!(File.join(this_example_root, 'views'))
|
50
|
+
ensure_asset_compiles!
|
51
|
+
|
52
|
+
expect(all_workaround_directories_in(this_example_root)).to eq([ ])
|
53
|
+
expect(all_workaround_directories_in(tempdir).length).to eq(1)
|
54
|
+
expect(all_workaround_directories_in(tempdir)[0]).to match(
|
55
|
+
/^#{Regexp.escape(File.join(tempdir, 'foo', 'bar', ::Parcels::Environment::PARCELS_WORKAROUND_DIRECTORY_NAME))}_[0-9a-f]{32}$/
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should let you re-set the workaround directory location to the same thing as much as you want" do
|
61
|
+
require 'tmpdir'
|
62
|
+
test_dir = Dir.mktmpdir do |tempdir|
|
63
|
+
sprockets_env.parcels.workaround_directories_root = File.join(tempdir, 'foo', 'bar')
|
64
|
+
sprockets_env.parcels.add_widget_tree!(File.join(this_example_root, 'views'))
|
65
|
+
ensure_asset_compiles!
|
66
|
+
|
67
|
+
sprockets_env.parcels.workaround_directories_root = File.join(tempdir, 'foo', 'bar')
|
68
|
+
ensure_asset_compiles!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should give you an exception if you try to change the workaround directory location after it's been used" do
|
73
|
+
sprockets_env.parcels.add_widget_tree!(File.join(this_example_root, 'views'))
|
74
|
+
ensure_asset_compiles!
|
75
|
+
|
76
|
+
expect do
|
77
|
+
sprockets_env.parcels.workaround_directories_root = this_example_root
|
78
|
+
end.to raise_exception(/can't set/)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parcels
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Geweke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -148,14 +148,14 @@ dependencies:
|
|
148
148
|
requirements:
|
149
149
|
- - ">="
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version: 0.9.
|
151
|
+
version: 0.9.2
|
152
152
|
type: :development
|
153
153
|
prerelease: false
|
154
154
|
version_requirements: !ruby/object:Gem::Requirement
|
155
155
|
requirements:
|
156
156
|
- - ">="
|
157
157
|
- !ruby/object:Gem::Version
|
158
|
-
version: 0.9.
|
158
|
+
version: 0.9.2
|
159
159
|
description: Allows you to package the CSS and Javascript for your view together with
|
160
160
|
that view, creating self-contained parcels of view code that seamlessly work together.
|
161
161
|
When used with Fortitude, automatically scopes your CSS, too. No more dueling CSS
|
@@ -169,6 +169,7 @@ files:
|
|
169
169
|
- ".gitignore"
|
170
170
|
- ".rspec-local"
|
171
171
|
- ".travis.yml"
|
172
|
+
- CHANGES.md
|
172
173
|
- Gemfile
|
173
174
|
- LICENSE.txt
|
174
175
|
- README.md
|
@@ -231,6 +232,8 @@ files:
|
|
231
232
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_and_inline_html.html.rb
|
232
233
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_erb.pcss
|
233
234
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_erb.rb
|
235
|
+
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module.rb
|
236
|
+
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module_test.rb
|
234
237
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/inline_erb.rb
|
235
238
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/multiple_engines.pcss
|
236
239
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/multiple_engines.rb
|
@@ -314,14 +317,17 @@ files:
|
|
314
317
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_one.rb
|
315
318
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_two.pcss
|
316
319
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_two.rb
|
320
|
+
- spec/system/ad_hoc_development_mode_spec.rb
|
317
321
|
- spec/system/alongside_file_spec.rb
|
318
322
|
- spec/system/autogenerated_class_application_spec.rb
|
319
323
|
- spec/system/basic_system_spec.rb
|
324
|
+
- spec/system/class_from_file_spec.rb
|
320
325
|
- spec/system/dependency_sorting_spec.rb
|
321
326
|
- spec/system/engines_spec.rb
|
322
327
|
- spec/system/prefix_spec.rb
|
323
328
|
- spec/system/sass_features_spec.rb
|
324
329
|
- spec/system/sets_spec.rb
|
330
|
+
- spec/system/workaround_directories_spec.rb
|
325
331
|
homepage: https://github.com/ageweke/parcels
|
326
332
|
licenses:
|
327
333
|
- MIT
|
@@ -384,6 +390,8 @@ test_files:
|
|
384
390
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_and_inline_html.html.rb
|
385
391
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_erb.pcss
|
386
392
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/alongside_erb.rb
|
393
|
+
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module.rb
|
394
|
+
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/helpers_module_test.rb
|
387
395
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/inline_erb.rb
|
388
396
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/multiple_engines.pcss
|
389
397
|
- spec/rails/templates/basic_rails_spec/app/views/basic_rails_spec/multiple_engines.rb
|
@@ -467,11 +475,15 @@ test_files:
|
|
467
475
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_one.rb
|
468
476
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_two.pcss
|
469
477
|
- spec/rails/templates/sets_rails_spec/app/views/sets_rails_spec/normal_two.rb
|
478
|
+
- spec/system/ad_hoc_development_mode_spec.rb
|
470
479
|
- spec/system/alongside_file_spec.rb
|
471
480
|
- spec/system/autogenerated_class_application_spec.rb
|
472
481
|
- spec/system/basic_system_spec.rb
|
482
|
+
- spec/system/class_from_file_spec.rb
|
473
483
|
- spec/system/dependency_sorting_spec.rb
|
474
484
|
- spec/system/engines_spec.rb
|
475
485
|
- spec/system/prefix_spec.rb
|
476
486
|
- spec/system/sass_features_spec.rb
|
477
487
|
- spec/system/sets_spec.rb
|
488
|
+
- spec/system/workaround_directories_spec.rb
|
489
|
+
has_rdoc:
|