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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 658277fafd37674b7c9be8026a325a2cb907f89c
4
- data.tar.gz: a1f74856053841ef8fb0573d246b64a712544c49
3
+ metadata.gz: f8c86251a8065212ca19858c38857005a7871457
4
+ data.tar.gz: 9be314a2db597e039c54dd4c4365e649e345fce5
5
5
  SHA512:
6
- metadata.gz: a589bcc70801b68c35d4d3b16e2a07e7863a199e211a96ca50f171dac1ea623215ed034084f8efcd7845b827565275eb51d832bd6a8a00bcf8f17f90d6606fcb
7
- data.tar.gz: 3005a5072e9d47179a0946ce166626cf6db502f9c99fe1f74b87014b57b2776369c1d04427a7f85be903a3d309d7002ca8a7abdad50d3327f8373343d90d8dd8
6
+ metadata.gz: 0507164165fabbce70addd13598209794d45bbfe414870db3cda85e8766de0edeca1597f973170b55444979443bd941823a00979396b3c5c7e8d02398d88be5b
7
+ data.tar.gz: 89b09a7873d8ebbf440aa06a8673bc7ddc66dd7e42975a0d72d3adf963cfddc649d252eef73691b595e25f1aa6d94da9392c5011ff222e724b506342eb43d54d
@@ -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/)).
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Andrew Geweke
1
+ Copyright (c) 2014-2015 Andrew Geweke
2
2
 
3
3
  MIT License
4
4
 
@@ -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(pathname)
34
- ::Fortitude::Widget.widget_class_from_file(pathname, :root_dirs => widget_trees.map(&:root))
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
@@ -24,7 +24,7 @@ module Parcels
24
24
  end
25
25
 
26
26
  def usable?
27
- widget_class_full_path
27
+ super && widget_class_full_path
28
28
  end
29
29
 
30
30
  private
@@ -26,7 +26,7 @@ module Parcels
26
26
  end
27
27
 
28
28
  def usable?
29
- true
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 ||= ::Fortitude::Widget.widget_class_from_file(widget_class_full_path, :root_dirs => [ widget_tree.root ])
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, :file, :line
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
- args = [ file ]
95
- if processor == ::Tilt::ScssTemplate && (::Parcels::Sprockets.requires_explicit_load_paths_for_css_template?)
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
@@ -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
- @_parcels_env_proxy ||= ::Parcels::Sprockets::StaticCompilerEnvProxy.new(@env)
109
+ ::Parcels::Sprockets::StaticCompilerEnvProxy.new(@env)
114
110
  end
115
111
  end
116
112
  end
117
113
  end
118
114
 
119
- begin
120
- require 'sass/rails/importer'
121
- rescue LoadError => le
122
- # oh, well
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
- parcels = context.environment.parcels
133
- expanded_locations_to_search = context.environment.paths + [ File.dirname(base) ]
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
- return find_relative_without_parcels(name, base, options.merge(:load_paths => expanded_locations_to_search))
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
 
@@ -1,3 +1,3 @@
1
1
  module Parcels
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
- all_parcels << parcel if parcel.usable? && parcel.included_in_any_set?(set_names)
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 ||= File.join(root, PARCELS_WORKAROUND_DIRECTORY_NAME)
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 == SYMLINK_TARGET
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(SYMLINK_TARGET, prefix)
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
@@ -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.1"
47
+ spec.add_development_dependency "fortitude", ">= 0.9.2"
48
48
  end
@@ -5,7 +5,7 @@ module ParcelsRailsHelpers
5
5
 
6
6
  def rails_server_additional_gemfile_lines
7
7
  [
8
- "gem 'fortitude', \">= 0.9.0\"",
8
+ "gem 'fortitude', \">= 0.9.2\"",
9
9
  "gem 'parcels', :path => '#{rails_server_project_root}'"
10
10
  ]
11
11
  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 @sprockets_env
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
- out.parcels.add_widget_tree!(File.join(this_example_root, 'views'))
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,5 @@
1
+ module Views::BasicRailsSpec::HelpersModule
2
+ def my_helper
3
+ text "this is my_helper!"
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class Views::BasicRailsSpec::HelpersModuleTest < Views::Widgets::Base
2
+ include Views::BasicRailsSpec::HelpersModule
3
+
4
+ css %{
5
+ p { color: green; }
6
+ }
7
+
8
+ def content
9
+ text "and it is "
10
+ my_helper
11
+ text " tada!"
12
+ end
13
+ 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/.parcels_sprockets_workaround/_parcels_alongside/my_widget.pcss' do
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.1
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: 2014-12-15 00:00:00.000000000 Z
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.1
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.1
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: