sass 3.2.0.alpha.269 → 3.2.0.alpha.273

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/REVISION CHANGED
@@ -1 +1 @@
1
- ce67165e9449e0a708282b04f163a3e8b8a8c370
1
+ 9b1820a2b092ba228eb20bea33b07ddd0793146f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.0.alpha.269
1
+ 3.2.0.alpha.273
@@ -973,23 +973,22 @@ module Sass::Script
973
973
 
974
974
  Sass::Util.check_range("Weight", 0..100, weight, '%')
975
975
 
976
- # This algorithm factors in both the user-provided weight
977
- # and the difference between the alpha values of the two colors
978
- # to decide how to perform the weighted average of the two RGB values.
976
+ # This algorithm factors in both the user-provided weight (w) and the
977
+ # difference between the alpha values of the two colors (a) to decide how
978
+ # to perform the weighted average of the two RGB values.
979
979
  #
980
980
  # It works by first normalizing both parameters to be within [-1, 1],
981
- # where 1 indicates "only use color1", -1 indicates "only use color 0",
982
- # and all values in between indicated a proportionately weighted average.
981
+ # where 1 indicates "only use color1", -1 indicates "only use color2", and
982
+ # all values in between indicated a proportionately weighted average.
983
983
  #
984
- # Once we have the normalized variables w and a,
985
- # we apply the formula (w + a)/(1 + w*a)
986
- # to get the combined weight (in [-1, 1]) of color1.
984
+ # Once we have the normalized variables w and a, we apply the formula
985
+ # (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of color1.
987
986
  # This formula has two especially nice properties:
988
987
  #
989
988
  # * When either w or a are -1 or 1, the combined weight is also that number
990
989
  # (cases where w * a == -1 are undefined, and handled as a special case).
991
990
  #
992
- # * When a is 0, the combined weight is w, and vice versa
991
+ # * When a is 0, the combined weight is w, and vice versa.
993
992
  #
994
993
  # Finally, the weight of color1 is renormalized to be within [0, 1]
995
994
  # and the weight of color2 is given by 1 minus the weight of color1.
@@ -36,7 +36,7 @@ module Sass::Script
36
36
  attr_accessor :original
37
37
 
38
38
  def self.precision
39
- @precision ||= 3
39
+ @precision ||= 5
40
40
  end
41
41
 
42
42
  # Sets the number of digits of precision
@@ -73,20 +73,6 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
73
73
  end
74
74
  end
75
75
 
76
- def invalid_function_parent?(parent, child)
77
- "Functions may only be defined at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
78
- end
79
-
80
- VALID_FUNCTION_CHILDREN = [
81
- Sass::Tree::CommentNode, Sass::Tree::DebugNode, Sass::Tree::ReturnNode,
82
- Sass::Tree::VariableNode, Sass::Tree::WarnNode
83
- ] + CONTROL_NODES
84
- def invalid_function_child?(parent, child)
85
- unless is_any_of?(child, VALID_FUNCTION_CHILDREN)
86
- "Functions can only contain variable declarations and control directives."
87
- end
88
- end
89
-
90
76
  INVALID_IMPORT_PARENTS = CONTROL_NODES +
91
77
  [Sass::Tree::MixinDefNode, Sass::Tree::MixinNode]
92
78
  def invalid_import_parent?(parent, child)
@@ -95,10 +81,6 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
95
81
  end
96
82
  return if parent.is_a?(Sass::Tree::RootNode)
97
83
  return "CSS import directives may only be used at the root of a document." if child.css_import?
98
- # If this is a nested @import, we need to make sure it doesn't have anything
99
- # that's legal at top-level but not in the current context (e.g. mixin defs).
100
- child.imported_file.to_tree.children.each {|c| visit(c)}
101
- nil
102
84
  rescue Sass::SyntaxError => e
103
85
  e.modify_backtrace(:filename => child.imported_file.options[:filename])
104
86
  e.add_backtrace(:filename => child.filename, :line => child.line)
@@ -106,7 +88,25 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
106
88
  end
107
89
 
108
90
  def invalid_mixindef_parent?(parent, child)
109
- "Mixins may only be defined at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
91
+ unless (@parents.map {|p| p.class} & INVALID_IMPORT_PARENTS).empty?
92
+ return "Mixins may not be defined within control directives or other mixins."
93
+ end
94
+ end
95
+
96
+ def invalid_function_parent?(parent, child)
97
+ unless (@parents.map {|p| p.class} & INVALID_IMPORT_PARENTS).empty?
98
+ return "Functions may not be defined within control directives or other mixins."
99
+ end
100
+ end
101
+
102
+ VALID_FUNCTION_CHILDREN = [
103
+ Sass::Tree::CommentNode, Sass::Tree::DebugNode, Sass::Tree::ReturnNode,
104
+ Sass::Tree::VariableNode, Sass::Tree::WarnNode
105
+ ] + CONTROL_NODES
106
+ def invalid_function_child?(parent, child)
107
+ unless is_any_of?(child, VALID_FUNCTION_CHILDREN)
108
+ "Functions can only contain variable declarations and control directives."
109
+ end
110
110
  end
111
111
 
112
112
  VALID_PROP_CHILDREN = [Sass::Tree::CommentNode, Sass::Tree::PropNode, Sass::Tree::MixinNode] + CONTROL_NODES
@@ -113,7 +113,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
113
113
 
114
114
  # Loads the function into the environment.
115
115
  def visit_function(node)
116
- @environment.set_function(node.name,
116
+ @environment.set_local_function(node.name,
117
117
  Sass::Callable.new(node.name, node.args, @environment, node.children, !:has_content))
118
118
  []
119
119
  end
@@ -155,7 +155,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
155
155
 
156
156
  # Loads a mixin into the environment.
157
157
  def visit_mixindef(node)
158
- @environment.set_mixin(node.name,
158
+ @environment.set_local_mixin(node.name,
159
159
  Sass::Callable.new(node.name, node.args, @environment, node.children, node.has_content))
160
160
  []
161
161
  end
@@ -59,9 +59,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
59
59
  return if node.invisible?
60
60
  spaces = (' ' * [@tabs - node.resolved_value[/^ */].size, 0].max)
61
61
 
62
- content = node.resolved_value.gsub(/^/, spaces).gsub(%r{^(\s*)//(.*)$}) do |md|
63
- "#{$1}/*#{$2} */"
64
- end
62
+ content = node.resolved_value.gsub(/^/, spaces)
63
+ content.gsub!(%r{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"} if node.type == :silent
65
64
  content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && node.type != :loud
66
65
  content
67
66
  end
@@ -73,7 +73,7 @@ MSG
73
73
  "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
74
74
  "=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.",
75
75
  "=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.",
76
- ".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2],
76
+ ".foo\n =foo\n :color red\n.bar\n +foo" => "Undefined mixin 'foo'.",
77
77
  " a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
78
78
  " \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
79
79
  "a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3],
@@ -105,7 +105,6 @@ MSG
105
105
  "@function foo($)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was "$)"', 1],
106
106
  "@function foo()\n @return" => 'Invalid @return: expected expression.',
107
107
  "@function foo()\n @return 1\n $var: val" => 'Illegal nesting: Nothing may be nested beneath return directives.',
108
- "foo\n @function bar()\n @return 1" => ['Functions may only be defined at the root of a document.', 2],
109
108
  "@function foo($a)\n @return 1\na\n b: foo()" => 'Function foo is missing argument $a',
110
109
  "@function foo()\n @return 1\na\n b: foo(2)" => 'Wrong number of arguments (1 for 0) for `foo\'',
111
110
  "@function foo()\n @return 1\na\n b: foo($a: 1)" => "Function foo doesn't have an argument named $a",
@@ -274,7 +273,7 @@ SASS
274
273
  end
275
274
 
276
275
  def test_imported_exception
277
- [1, 2, 3, 4, 5].each do |i|
276
+ [1, 2, 3, 4].each do |i|
278
277
  begin
279
278
  Sass::Engine.new("@import bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
280
279
  rescue Sass::SyntaxError => err
@@ -296,7 +295,7 @@ SASS
296
295
  end
297
296
 
298
297
  def test_double_imported_exception
299
- [1, 2, 3, 4, 5].each do |i|
298
+ [1, 2, 3, 4].each do |i|
300
299
  begin
301
300
  Sass::Engine.new("@import nested_bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
302
301
  rescue Sass::SyntaxError => err
@@ -723,24 +722,6 @@ CSS
723
722
  SASS
724
723
  end
725
724
 
726
- def test_nested_import_with_toplevel_constructs
727
- Sass::Engine.new(".foo\n @import importee", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
728
- rescue Sass::SyntaxError => err
729
- assert_equal(3, err.sass_line)
730
- assert_match(/(\/|^)importee\.sass$/, err.sass_filename)
731
-
732
- assert_hash_has(err.sass_backtrace.first,
733
- :filename => err.sass_filename, :line => err.sass_line)
734
-
735
- assert_nil(err.sass_backtrace[1][:filename])
736
- assert_equal(2, err.sass_backtrace[1][:line])
737
-
738
- assert_match(/(\/|^)importee\.sass:3$/, err.backtrace.first)
739
- assert_equal("(sass):2", err.backtrace[1])
740
- else
741
- assert(false, "Exception not raised for importing mixins nested")
742
- end
743
-
744
725
  def test_units
745
726
  renders_correctly "units"
746
727
  end
@@ -1027,6 +1027,21 @@ bar {baz: bang}
1027
1027
  SCSS
1028
1028
  end
1029
1029
 
1030
+ def test_single_line_comment_within_multiline_comment
1031
+ assert_equal(<<CSS, render(<<SCSS))
1032
+ body {
1033
+ /*
1034
+ //comment here
1035
+ */ }
1036
+ CSS
1037
+ body {
1038
+ /*
1039
+ //comment here
1040
+ */
1041
+ }
1042
+ SCSS
1043
+ end
1044
+
1030
1045
  private
1031
1046
 
1032
1047
  def assert_selector_parses(selector)
@@ -1073,17 +1073,83 @@ $domain: "sass-lang.com";
1073
1073
  SCSS
1074
1074
  end
1075
1075
 
1076
+ def test_nested_mixin_def
1077
+ assert_equal <<CSS, render(<<SCSS)
1078
+ foo {
1079
+ a: b; }
1080
+ CSS
1081
+ foo {
1082
+ @mixin bar {a: b}
1083
+ @include bar; }
1084
+ SCSS
1085
+ end
1086
+
1087
+ def test_nested_mixin_shadow
1088
+ assert_equal <<CSS, render(<<SCSS)
1089
+ foo {
1090
+ c: d; }
1091
+
1092
+ baz {
1093
+ a: b; }
1094
+ CSS
1095
+ @mixin bar {a: b}
1096
+
1097
+ foo {
1098
+ @mixin bar {c: d}
1099
+ @include bar;
1100
+ }
1101
+
1102
+ baz {@include bar}
1103
+ SCSS
1104
+ end
1105
+
1106
+ def test_nested_function_def
1107
+ assert_equal <<CSS, render(<<SCSS)
1108
+ foo {
1109
+ a: 1; }
1110
+
1111
+ bar {
1112
+ b: foo(); }
1113
+ CSS
1114
+ foo {
1115
+ @function foo() {@return 1}
1116
+ a: foo(); }
1117
+
1118
+ bar {b: foo()}
1119
+ SCSS
1120
+ end
1121
+
1122
+ def test_nested_function_shadow
1123
+ assert_equal <<CSS, render(<<SCSS)
1124
+ foo {
1125
+ a: 2; }
1126
+
1127
+ baz {
1128
+ b: 1; }
1129
+ CSS
1130
+ @function foo() {@return 1}
1131
+
1132
+ foo {
1133
+ @function foo() {@return 2}
1134
+ a: foo();
1135
+ }
1136
+
1137
+ baz {b: foo()}
1138
+ SCSS
1139
+ end
1140
+
1076
1141
  ## Errors
1077
1142
 
1078
- def test_mixin_defs_only_at_toplevel
1143
+ def test_nested_mixin_def_is_scoped
1079
1144
  render <<SCSS
1080
1145
  foo {
1081
1146
  @mixin bar {a: b}}
1147
+ bar {@include bar}
1082
1148
  SCSS
1083
1149
  assert(false, "Expected syntax error")
1084
1150
  rescue Sass::SyntaxError => e
1085
- assert_equal "Mixins may only be defined at the root of a document.", e.message
1086
- assert_equal 2, e.sass_line
1151
+ assert_equal "Undefined mixin 'bar'.", e.message
1152
+ assert_equal 3, e.sass_line
1087
1153
  end
1088
1154
 
1089
1155
  def test_rules_beneath_properties
@@ -1,23 +1,63 @@
1
+ ## 0.4.7 - June 27, 2012
2
+
3
+ ### Bug fixes
4
+
5
+ - Increase latency to 0.25, to avoid useless polling fallback. (fixed by [@thibaudgg][])
6
+ - Change watched inotify events, to avoid duplication callback. (fixed by [@thibaudgg][])
7
+ - [#41](https://github.com/guard/listen/issues/41) Use lstat instead of stat when calculating mtime. (fixed by [@ebroder][])
8
+
9
+ ## 0.4.6 - June 20, 2012
10
+
11
+ ### Bug fix
12
+
13
+ - [#39](https://github.com/guard/listen/issues/39) Fix digest race condition. (fixed by [@dkubb][])
14
+
15
+ ## 0.4.5 - June 13, 2012
16
+
17
+ ### Bug fix
18
+
19
+ - [#39](https://github.com/guard/listen/issues/39) Rescue Errno::ENOENT when path inserted doesn't exist. (reported by [@textgoeshere][], fixed by [@thibaudgg][] and [@rymai][])
20
+
21
+ ## 0.4.4 - June 8, 2012
22
+
23
+ ### Bug fixes
24
+
25
+ - ~~[#39](https://github.com/guard/listen/issues/39) Non-existing path insertion bug. (reported by [@textgoeshere][], fixed by [@thibaudgg][])~~
26
+ - Fix relative path for directories containing special characters. (reported by [@napcs][], fixed by [@netzpirat][])
27
+
28
+ ## 0.4.3 - June 6, 2012
29
+
30
+ ### Bug fixes
31
+
32
+ - [#24](https://github.com/guard/listen/issues/24) Fail gracefully when the inotify limit is not enough for Listen to function. (reported by [@daemonza][], fixed by [@Maher4Ever][])
33
+ - [#32](https://github.com/guard/listen/issues/32) Fix a crash when trying to calculate the checksum of unreadable files. (reported by [@nex3][], fixed by [@Maher4Ever][])
34
+
35
+ ### Improvements
36
+
37
+ - Add `#relative_paths` method to listeners. ([@Maher4Ever][])
38
+ - Add `#started?` query-method to adapters. ([@Maher4Ever][])
39
+ - Dynamically detect the mtime precision used on a system. ([@Maher4Ever][] with help from [@nex3][])
40
+
1
41
  ## 0.4.2 - May 1, 2012
2
42
 
3
43
  ### Bug fixes
4
44
 
5
- - [#21](https://github.com/guard/listen/issues/21): Issues when listening to changes in relative paths. (reported by [@akerbos][], fixed by [@Maher4Ever][])
6
- - [#27](https://github.com/guard/listen/issues/27): Wrong reports for files modifications. (reported by [@cobychapple][], fixed by [@Maher4Ever][])
45
+ - [#21](https://github.com/guard/listen/issues/21) Issues when listening to changes in relative paths. (reported by [@akerbos][], fixed by [@Maher4Ever][])
46
+ - [#27](https://github.com/guard/listen/issues/27) Wrong reports for files modifications. (reported by [@cobychapple][], fixed by [@Maher4Ever][])
7
47
  - Fix segmentation fault when profiling on Windows. ([@Maher4Ever][])
8
48
  - Fix redundant watchers on Windows. ([@Maher4Ever][])
9
49
 
10
50
  ### Improvements
11
51
 
12
- - [#17](https://github.com/guard/listen/issues/17): Use regexp-patterns with the `ignore` method instead of supplying paths. (reported by [@fny][], added by [@Maher4Ever][])
52
+ - [#17](https://github.com/guard/listen/issues/17) Use regexp-patterns with the `ignore` method instead of supplying paths. (reported by [@fny][], added by [@Maher4Ever][])
13
53
  - Speed improvement when listening to changes in directories with ignored paths. ([@Maher4Ever][])
14
54
  - Added `.rbx` and `.svn` to ignored directories. ([@Maher4Ever][])
15
55
 
16
56
  ## 0.4.1 - April 15, 2012
17
57
 
18
- ### Bug fixes
58
+ ### Bug fix
19
59
 
20
- - [#18]((https://github.com/guard/listen/issues/18): Listener crashes when removing directories with nested paths. (reported by [@daemonza][], fixed by [@Maher4Ever][])
60
+ - [#18](https://github.com/guard/listen/issues/18) Listener crashes when removing directories with nested paths. (reported by [@daemonza][], fixed by [@Maher4Ever][])
21
61
 
22
62
  ## 0.4.0 - April 9, 2012
23
63
 
@@ -37,19 +77,19 @@
37
77
  - Encapsulate thread spawning in the windows-adapter. ([@Maher4Ever][])
38
78
  - Fix linux-adapter bug where Listen would report file-modification events on the parent-directory. ([@Maher4Ever][])
39
79
 
40
- ### Removals
80
+ ### Change
41
81
 
42
82
  - Remove `wait_until_listening` as adapters doesn't need to run inside threads anymore ([@Maher4Ever][])
43
83
 
44
84
  ## 0.3.3 - March 6, 2012
45
85
 
46
- ### Improvements
86
+ ### Improvement
47
87
 
48
88
  - Improve pause/unpause. ([@thibaudgg][])
49
89
 
50
90
  ## 0.3.2 - March 4, 2012
51
91
 
52
- ### New features
92
+ ### New feature
53
93
 
54
94
  - Add pause/unpause listener's methods. ([@thibaudgg][])
55
95
 
@@ -57,7 +97,7 @@
57
97
 
58
98
  ### Bug fix
59
99
 
60
- - [#9](https://github.com/guard/listen/issues/9): Ignore doesn't seem to work. (reported by [@markiz][], fixed by [@thibaudgg][])
100
+ - [#9](https://github.com/guard/listen/issues/9) Ignore doesn't seem to work. (reported by [@markiz][], fixed by [@thibaudgg][])
61
101
 
62
102
  ## 0.3.0 - February 21, 2012
63
103
 
@@ -81,10 +121,27 @@
81
121
 
82
122
  - First version with only a polling adapter and basic features set (ignore & filter). ([@thibaudgg][])
83
123
 
84
- [@markiz]: https://github.com/markiz
85
- [@thibaudgg]: https://github.com/thibaudgg
124
+ <!--- The following link definition list is generated by PimpMyChangelog --->
125
+ [#9]: https://github.com/guard/listen/issues/9
126
+ [#17]: https://github.com/guard/listen/issues/17
127
+ [#18]: https://github.com/guard/listen/issues/18
128
+ [#21]: https://github.com/guard/listen/issues/21
129
+ [#24]: https://github.com/guard/listen/issues/24
130
+ [#27]: https://github.com/guard/listen/issues/27
131
+ [#32]: https://github.com/guard/listen/issues/32
132
+ [#39]: https://github.com/guard/listen/issues/39
86
133
  [@Maher4Ever]: https://github.com/Maher4Ever
87
- [@daemonza]: https://github.com/daemonza
134
+ [@dkubb]: https://github.com/dkubb
135
+ [@ebroder]: https://github.com/ebroder
88
136
  [@akerbos]: https://github.com/akerbos
89
- [@fny]: https://github.com/fny
90
137
  [@cobychapple]: https://github.com/cobychapple
138
+ [@daemonza]: https://github.com/daemonza
139
+ [@fny]: https://github.com/fny
140
+ [@markiz]: https://github.com/markiz
141
+ [@napcs]: https://github.com/napcs
142
+ [@netzpirat]: https://github.com/netzpirat
143
+ [@nex3]: https://github.com/nex3
144
+ [@rymai]: https://github.com/rymai
145
+ [@scottdavis]: https://github.com/scottdavis
146
+ [@textgoeshere]: https://github.com/textgoeshere
147
+ [@thibaudgg]: https://github.com/thibaudgg
@@ -6,23 +6,11 @@ gem 'rake'
6
6
 
7
7
  group :development do
8
8
  platform :ruby do
9
- gem 'rb-readline'
9
+ gem 'coolline'
10
10
  end
11
11
 
12
- require 'rbconfig'
13
- case RbConfig::CONFIG['target_os']
14
- when /darwin/i
15
- # gem 'ruby_gntp', '~> 0.3.4', :require => false
16
- gem 'growl', :require => false
17
- when /linux/i
18
- gem 'libnotify', '~> 0.7.1', :require => false
19
- when /mswin|mingw/i
20
- gem 'win32console', :require => false
21
- gem 'rb-notifu', '>= 0.0.4', :require => false
22
- end
23
-
24
- gem 'guard', '~> 1.0.0'
25
- gem 'guard-rspec', '~> 0.7.0'
12
+ gem 'guard'
13
+ gem 'guard-rspec'
26
14
  gem 'yard'
27
15
  gem 'redcarpet'
28
16
  gem 'pry'
@@ -31,5 +19,5 @@ group :development do
31
19
  end
32
20
 
33
21
  group :test do
34
- gem 'rspec', '~> 2.9.0'
22
+ gem 'rspec'
35
23
  end
@@ -32,12 +32,12 @@ Feel free to give your feeback via [Listen issues](https://github.com/guard/list
32
32
 
33
33
  ``` ruby
34
34
  # Listen to a single directory.
35
- Listen.to('dir/path/to/listen', filter: /\.rb$/, ignore: %r{ignored/path/}) do |modified, added, removed|
35
+ Listen.to('dir/path/to/listen', :filter => /\.rb$/, :ignore => %r{ignored/path/}) do |modified, added, removed|
36
36
  # ...
37
37
  end
38
38
 
39
39
  # Listen to multiple directories.
40
- Listen.to('dir/to/awesome_app', 'dir/to/other_app', filter: /\.rb$/, latency: 0.1) do |modified, added, removed|
40
+ Listen.to('dir/to/awesome_app', 'dir/to/other_app', :filter => /\.rb$/, :latency => 0.1) do |modified, added, removed|
41
41
  # ...
42
42
  end
43
43
  ```
@@ -191,7 +191,7 @@ These options can be set through `Listen.to` params or via methods (see the "Obj
191
191
  # default: See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::DirectoryRecord
192
192
 
193
193
  :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
194
- # default: 0.1 sec (1.0 sec for polling)
194
+ # default: 0.25 sec (1.0 sec for polling)
195
195
 
196
196
  :relative_paths => true # Enable the use of relative paths in the callback.
197
197
  # default: false
@@ -8,7 +8,7 @@ module Listen
8
8
  attr_accessor :directories, :latency, :paused
9
9
 
10
10
  # The default delay between checking for changes.
11
- DEFAULT_LATENCY = 0.1
11
+ DEFAULT_LATENCY = 0.25
12
12
 
13
13
  # The default warning message when falling back to polling adapter.
14
14
  POLLING_FALLBACK_MESSAGE = "WARNING: Listen has fallen back to polling, learn more at https://github.com/guard/listen#fallback."
@@ -10,7 +10,7 @@ module Listen
10
10
  # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
11
11
  # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
12
12
  #
13
- EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
13
+ EVENTS = %w[recursive attrib create delete move close_write]
14
14
 
15
15
  # The message to show when the limit of inotify watchers is not enough
16
16
  #
@@ -163,7 +163,7 @@ module Listen
163
163
  #
164
164
  def relative_to_base(path)
165
165
  return nil unless path[@directory]
166
- path.sub(%r{^#{@directory}#{File::SEPARATOR}?}, '')
166
+ path.sub(%r{^#{Regexp.quote(@directory)}#{File::SEPARATOR}?}, '')
167
167
  end
168
168
 
169
169
  private
@@ -239,8 +239,8 @@ module Listen
239
239
  elsif !ignored?(path) && filtered?(path) && !existing_path?(path)
240
240
  if File.file?(path)
241
241
  @changes[:added] << (options[:relative_paths] ? relative_to_base(path) : path)
242
+ insert_path(path)
242
243
  end
243
- insert_path(path)
244
244
  end
245
245
  end
246
246
  end
@@ -253,11 +253,11 @@ module Listen
253
253
  def content_modified?(path)
254
254
  sha1_checksum = Digest::SHA1.file(path).to_s
255
255
  return false if @sha1_checksums[path] == sha1_checksum
256
-
257
- had_no_checksum = @sha1_checksums[path].nil?
258
- @sha1_checksums[path] = sha1_checksum
259
-
260
- had_no_checksum ? false : true
256
+ @sha1_checksums.key?(path)
257
+ rescue Errno::EACCES, Errno::ENOENT
258
+ false
259
+ ensure
260
+ @sha1_checksums[path] = sha1_checksum if sha1_checksum
261
261
  end
262
262
 
263
263
  # Traverses the base directory looking for paths that should
@@ -292,6 +292,7 @@ module Listen
292
292
  meta_data.type = File.directory?(path) ? 'Dir' : 'File'
293
293
  meta_data.mtime = mtime_of(path) unless meta_data.type == 'Dir' # mtimes of dirs are not used yet
294
294
  @paths[File.dirname(path)][File.basename(path)] = meta_data
295
+ rescue Errno::ENOENT
295
296
  end
296
297
 
297
298
  # Returns whether or not a path exists in the paths hash.
@@ -311,7 +312,7 @@ module Listen
311
312
  # @return [Fixnum, Float] the mtime of the file
312
313
  #
313
314
  def mtime_of(file)
314
- File.mtime(file).send(HIGH_PRECISION_SUPPORTED ? :to_f : :to_i)
315
+ File.lstat(file).mtime.send(HIGH_PRECISION_SUPPORTED ? :to_f : :to_i)
315
316
  end
316
317
  end
317
318
  end
@@ -1,3 +1,3 @@
1
1
  module Listen
2
- VERSION = '0.4.2'
2
+ VERSION = '0.4.7'
3
3
  end
@@ -193,6 +193,25 @@ describe Listen::DirectoryRecord do
193
193
  it 'returns nil when the passed path is not inside the base-directory' do
194
194
  subject.relative_to_base('/tmp/some_random_path').should be_nil
195
195
  end
196
+
197
+ context 'when containing regexp characters in the base directory' do
198
+ before do
199
+ fixtures do |path|
200
+ mkdir 'a_directory$'
201
+ @dir = described_class.new(path + '/a_directory$')
202
+ @dir.build
203
+ end
204
+ end
205
+
206
+ it 'removes the path of the base-directory from the passed path' do
207
+ path = 'dir/to/app/file.rb'
208
+ @dir.relative_to_base(File.join(@dir.directory, path)).should eq path
209
+ end
210
+
211
+ it 'returns nil when the passed path is not inside the base-directory' do
212
+ @dir.relative_to_base('/tmp/some_random_path').should be_nil
213
+ end
214
+ end
196
215
  end
197
216
 
198
217
  describe '#fetch_changes' do
@@ -385,7 +404,7 @@ describe Listen::DirectoryRecord do
385
404
  end
386
405
  end
387
406
 
388
- context '#27 - when a file is created and then checked for modifications at the same second' do
407
+ context 'when a file is created and then checked for modifications at the same second - #27' do
389
408
  # This issue was the result of checking a file for content changes when
390
409
  # the mtime and the checking time are the same. In this case there
391
410
  # is no checksum saved, so the file was reported as being changed.
@@ -1030,5 +1049,90 @@ describe Listen::DirectoryRecord do
1030
1049
  end
1031
1050
  end
1032
1051
  end
1052
+
1053
+ context 'within a directory containing unreadble paths - #32' do
1054
+ it 'detects changes more than a second apart' do
1055
+ fixtures do |path|
1056
+ touch 'unreadable_file.txt'
1057
+ chmod 000, 'unreadable_file.txt'
1058
+
1059
+ modified, added, removed = changes(path) do
1060
+ sleep 1.1
1061
+ touch 'unreadable_file.txt'
1062
+ end
1063
+
1064
+ added.should be_empty
1065
+ modified.should =~ %w(unreadable_file.txt)
1066
+ removed.should be_empty
1067
+ end
1068
+ end
1069
+
1070
+ context 'with multiple changes within the same second' do
1071
+ before { ensure_same_second }
1072
+
1073
+ it 'does not detect changes even if content changes', :unless => described_class::HIGH_PRECISION_SUPPORTED do
1074
+ fixtures do |path|
1075
+ touch 'unreadable_file.txt'
1076
+
1077
+ modified, added, removed = changes(path) do
1078
+ open('unreadable_file.txt', 'w') { |f| f.write('foo') }
1079
+ chmod 000, 'unreadable_file.txt'
1080
+ end
1081
+
1082
+ added.should be_empty
1083
+ modified.should be_empty
1084
+ removed.should be_empty
1085
+ end
1086
+ end
1087
+ end
1088
+ end
1089
+
1090
+ context 'within a directory containing a removed file - #39' do
1091
+ it 'does not raise an exception when hashing a removed file' do
1092
+
1093
+ # simulate a race condition where the file is removed after the
1094
+ # change event is tracked, but before the hash is calculated
1095
+ Digest::SHA1.should_receive(:file).and_raise(Errno::ENOENT)
1096
+
1097
+ lambda {
1098
+ fixtures do |path|
1099
+ file = 'removed_file.txt'
1100
+ touch file
1101
+ changes(path) { touch file }
1102
+ end
1103
+ }.should_not raise_error(Errno::ENOENT)
1104
+ end
1105
+ end
1106
+
1107
+ context 'with symlinks' do
1108
+ it 'looks at symlinks not their targets' do
1109
+ fixtures do |path|
1110
+ touch 'target'
1111
+ symlink 'target', 'symlink'
1112
+
1113
+ record = described_class.new(path)
1114
+ record.build
1115
+
1116
+ sleep 1
1117
+ touch 'target'
1118
+
1119
+ record.fetch_changes([path], :relative_paths => true)[:modified].should == ['target']
1120
+ end
1121
+ end
1122
+
1123
+ it 'handles broken symlinks' do
1124
+ fixtures do |path|
1125
+ symlink 'target', 'symlink'
1126
+
1127
+ record = described_class.new(path)
1128
+ record.build
1129
+
1130
+ sleep 1
1131
+ rm 'symlink'
1132
+ symlink 'new-target', 'symlink'
1133
+ record.fetch_changes([path], :relative_paths => true)
1134
+ end
1135
+ end
1136
+ end
1033
1137
  end
1034
1138
  end
@@ -1,14 +1,16 @@
1
1
  require 'listen'
2
2
 
3
- ENV["TEST_LATENCY"] ||= "0.1"
3
+ ENV["TEST_LATENCY"] ||= "0.25"
4
4
 
5
5
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
6
6
 
7
7
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
8
8
  RSpec.configure do |config|
9
+ config.color_enabled = true
10
+ config.order = :random
11
+ config.filter_run :focus => true
9
12
  config.treat_symbols_as_metadata_keys_with_true_values = true
10
13
  config.run_all_when_everything_filtered = true
11
- config.filter_run :focus
12
14
  end
13
15
 
14
16
  def test_latency
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- hash: 592302343
4
+ hash: 592302399
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
9
  - 0
10
10
  - alpha
11
- - 269
12
- version: 3.2.0.alpha.269
11
+ - 273
12
+ version: 3.2.0.alpha.273
13
13
  platform: ruby
14
14
  authors:
15
15
  - Nathan Weizenbaum
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2012-07-13 00:00:00 -04:00
22
+ date: 2012-07-20 00:00:00 -04:00
23
23
  default_executable:
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
@@ -110,10 +110,10 @@ files:
110
110
  - lib/sass/script/list.rb
111
111
  - lib/sass/script/literal.rb
112
112
  - lib/sass/script/node.rb
113
- - lib/sass/script/null.rb
114
113
  - lib/sass/script/number.rb
115
114
  - lib/sass/script/operation.rb
116
115
  - lib/sass/script/parser.rb
116
+ - lib/sass/script/null.rb
117
117
  - lib/sass/script/string.rb
118
118
  - lib/sass/script/string_interpolation.rb
119
119
  - lib/sass/script/unary_operation.rb
@@ -154,6 +154,7 @@ files:
154
154
  - lib/sass/tree/content_node.rb
155
155
  - lib/sass/tree/css_import_node.rb
156
156
  - lib/sass/tree/variable_node.rb
157
+ - lib/sass/tree/warn_node.rb
157
158
  - lib/sass/tree/visitors/base.rb
158
159
  - lib/sass/tree/visitors/check_nesting.rb
159
160
  - lib/sass/tree/visitors/convert.rb
@@ -163,7 +164,6 @@ files:
163
164
  - lib/sass/tree/visitors/perform.rb
164
165
  - lib/sass/tree/visitors/set_options.rb
165
166
  - lib/sass/tree/visitors/to_css.rb
166
- - lib/sass/tree/warn_node.rb
167
167
  - lib/sass/tree/while_node.rb
168
168
  - lib/sass/tree/supports_node.rb
169
169
  - lib/sass/tree/trace_node.rb
@@ -275,7 +275,6 @@ files:
275
275
  - test/sass/templates/bork2.sass
276
276
  - test/sass/templates/bork3.sass
277
277
  - test/sass/templates/bork4.sass
278
- - test/sass/templates/bork5.sass
279
278
  - test/sass/templates/compact.sass
280
279
  - test/sass/templates/complex.sass
281
280
  - test/sass/templates/compressed.sass
@@ -298,7 +297,6 @@ files:
298
297
  - test/sass/templates/nested_bork2.sass
299
298
  - test/sass/templates/nested_bork3.sass
300
299
  - test/sass/templates/nested_bork4.sass
301
- - test/sass/templates/nested_bork5.sass
302
300
  - test/sass/templates/nested_import.sass
303
301
  - test/sass/templates/nested_mixin_bork.sass
304
302
  - test/sass/templates/options.sass
@@ -1,3 +0,0 @@
1
- foo
2
- @function bar($a)
3
- @return $a
@@ -1,2 +0,0 @@
1
-
2
- @import bork5