css_splitter_opp_fork 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +99 -0
  4. data/Rakefile +40 -0
  5. data/app/helpers/css_splitter/application_helper.rb +20 -0
  6. data/config/routes.rb +2 -0
  7. data/lib/css_splitter/engine.rb +15 -0
  8. data/lib/css_splitter/splitter.rb +112 -0
  9. data/lib/css_splitter/sprockets_engine.rb +23 -0
  10. data/lib/css_splitter/version.rb +3 -0
  11. data/lib/css_splitter.rb +6 -0
  12. data/lib/tasks/css_splitter_tasks.rake +4 -0
  13. data/test/css_splitter_test.rb +41 -0
  14. data/test/dummy/README.rdoc +261 -0
  15. data/test/dummy/Rakefile +7 -0
  16. data/test/dummy/app/assets/stylesheets/application.css +16 -0
  17. data/test/dummy/app/assets/stylesheets/combined.css.scss +4 -0
  18. data/test/dummy/app/assets/stylesheets/combined_split2.css +3 -0
  19. data/test/dummy/app/assets/stylesheets/erb_stylesheet.css.scss.erb +7 -0
  20. data/test/dummy/app/assets/stylesheets/erb_stylesheet_split2.css +3 -0
  21. data/test/dummy/app/assets/stylesheets/erb_stylesheet_split3.css +3 -0
  22. data/test/dummy/app/assets/stylesheets/green_max.css.scss.erb +3 -0
  23. data/test/dummy/app/assets/stylesheets/red_100.css.scss.erb +3 -0
  24. data/test/dummy/app/assets/stylesheets/test_stylesheet_with_media_queries.css +19145 -0
  25. data/test/dummy/app/assets/stylesheets/test_stylesheet_with_media_queries_split2.css +3 -0
  26. data/test/dummy/app/assets/stylesheets/too_big_stylesheet.css.scss +4100 -0
  27. data/test/dummy/app/assets/stylesheets/too_big_stylesheet_split2.css +3 -0
  28. data/test/dummy/app/controllers/application_controller.rb +3 -0
  29. data/test/dummy/app/controllers/tests_controller.rb +4 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +17 -0
  31. data/test/dummy/app/views/tests/test.html.erb +12 -0
  32. data/test/dummy/config/application.rb +64 -0
  33. data/test/dummy/config/boot.rb +10 -0
  34. data/test/dummy/config/database.yml +25 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +39 -0
  37. data/test/dummy/config/environments/production.rb +69 -0
  38. data/test/dummy/config/environments/test.rb +39 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/inflections.rb +15 -0
  41. data/test/dummy/config/initializers/mime_types.rb +5 -0
  42. data/test/dummy/config/initializers/secret_token.rb +7 -0
  43. data/test/dummy/config/initializers/session_store.rb +8 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +5 -0
  46. data/test/dummy/config/routes.rb +5 -0
  47. data/test/dummy/config.ru +4 -0
  48. data/test/dummy/public/404.html +26 -0
  49. data/test/dummy/public/422.html +26 -0
  50. data/test/dummy/public/500.html +25 -0
  51. data/test/dummy/public/favicon.ico +0 -0
  52. data/test/dummy/script/rails +6 -0
  53. data/test/integration/navigation_test.rb +10 -0
  54. data/test/test_helper.rb +15 -0
  55. data/test/unit/helpers/css_splitter/application_helper_test.rb +22 -0
  56. data/test/unit/splitter_test.rb +192 -0
  57. data/test/unit/too_many_selectors.css +12986 -0
  58. metadata +176 -0
@@ -0,0 +1,192 @@
1
+ require 'test_helper'
2
+
3
+ class CssSplitterTest < ActiveSupport::TestCase
4
+ test "#count_selectors" do
5
+ assert_equal 2937, CssSplitter::Splitter.count_selectors('test/unit/too_many_selectors.css')
6
+ end
7
+
8
+ test "#count_selectors_of_rule" do
9
+ assert_equal 1, CssSplitter::Splitter.count_selectors_of_rule('foo { color: baz; }')
10
+ assert_equal 2, CssSplitter::Splitter.count_selectors_of_rule('foo, bar { color: baz; }')
11
+
12
+ # split_string_into_rules splits the closing brace of a media query into its own rule
13
+ assert_equal 0, CssSplitter::Splitter.count_selectors_of_rule('}')
14
+ end
15
+
16
+ # --- split_string_into_rules ---
17
+
18
+ test '#split_string_into_rules' do
19
+ simple = "a{foo:bar;}b{baz:qux;}"
20
+ assert_equal ["a{foo:bar;}", "b{baz:qux;}"], CssSplitter::Splitter.split_string_into_rules(simple)
21
+ end
22
+
23
+ test '#split_string_into_rules for single line comments' do
24
+ multi_line = "a{foo:bar;} /* comment p{bar:foo;} */ b{baz:qux;}"
25
+ assert_equal ["a{foo:bar;}", " b{baz:qux;}"], CssSplitter::Splitter.split_string_into_rules(multi_line)
26
+ end
27
+
28
+ test '#split_string_into_rules for multiline comments' do
29
+ multi_line = "a{foo:bar;}\n/*\nMultiline comment p{bar:foo;}\n*/\nb{baz:qux;}"
30
+ assert_equal ["a{foo:bar;}", "\n\nb{baz:qux;}"], CssSplitter::Splitter.split_string_into_rules(multi_line)
31
+ end
32
+
33
+ test '#split_string_into_rules for strings with protocol independent urls' do
34
+ simple = "a{foo:url(//assets.server.com);}b{bar:url(//assets/server.com);}"
35
+ assert_equal ["a{foo:url(//assets.server.com);}", "b{bar:url(//assets/server.com);}"], CssSplitter::Splitter.split_string_into_rules(simple)
36
+ end
37
+
38
+ test '#split_string_into_rules containing media queries' do
39
+ has_media = "a{foo:bar;}@media print{b{baz:qux;}c{quux:corge;}}d{grault:garply;}"
40
+ assert_equal ["a{foo:bar;}", "@media print{b{baz:qux;}", "c{quux:corge;}", "}", "d{grault:garply;}"], CssSplitter::Splitter.split_string_into_rules(has_media)
41
+ end
42
+
43
+ # --- extract_charset ---
44
+
45
+ test '#extract_charset with no charset' do
46
+ first_rule = ".foo { color: black; }"
47
+ assert_equal [nil, first_rule], CssSplitter::Splitter.send(:extract_charset, first_rule)
48
+ end
49
+
50
+ test '#extract_charset with charset' do
51
+ first_rule = '@charset "UTF-8"; .foo { color: black; }'
52
+ assert_equal ['@charset "UTF-8";', ' .foo { color: black; }'], CssSplitter::Splitter.send(:extract_charset, first_rule)
53
+ end
54
+
55
+ # --- extract_media ---
56
+
57
+ test '#extract_media with no media block' do
58
+ first_rule = ".foo { color: black; }"
59
+ assert_equal nil, CssSplitter::Splitter.send(:extract_media, first_rule)
60
+ end
61
+
62
+ test '#extract_media with media block' do
63
+ first_rule = <<EOD
64
+ @media only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 768px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 1280px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 800px) {
65
+ .foo { color: black; }
66
+ }
67
+ EOD
68
+ assert_equal '@media only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 768px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 1280px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 800px) {', CssSplitter::Splitter.send(:extract_media, first_rule)
69
+ end
70
+
71
+ # --- split_string ---
72
+
73
+ test '#split_string to get the second split' do
74
+ assert_equal "@charset \"UTF-8\";\n#test { background-color: green ;}", CssSplitter::Splitter.split_string(File.read('test/dummy/app/assets/stylesheets/too_big_stylesheet.css.scss'), 2)
75
+ end
76
+
77
+ test '#split_string where the media part would overlap the split, all rules in media before the split, closing would end up in second part' do
78
+ # This tests the following situation:
79
+ # Part 1: CssSplitter::Splitter::MAX_SELECTORS_DEFAULT - 1
80
+ # + Media block and first rule inside the media block
81
+ # Part 2: Ignore the close tag of the media block and outputs the last rule outside the media block
82
+
83
+ # Change this line to any number, for example 4, if it fails to ease debugging
84
+ max_selectors = CssSplitter::Splitter::MAX_SELECTORS_DEFAULT
85
+
86
+ css_rules = []
87
+ (max_selectors - 1).times do |n|
88
+ css_rules << ".a#{n} { color: black; }"
89
+ end
90
+ css_rules << "@media only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 768px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 1280px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 800px) {"
91
+ css_rules << ".first-in-media-after-split { color: black; } }"
92
+ last_part = ".first-after-media { color: black; }"
93
+
94
+ first_contents = css_rules.join("").gsub(/\s/, '')
95
+ last_contents = last_part.gsub(/\s/, '')
96
+ css_contents = "#{first_contents}#{last_contents}"
97
+
98
+ assert_equal first_contents, CssSplitter::Splitter.split_string(css_contents, 1, max_selectors)
99
+ assert_equal last_contents, CssSplitter::Splitter.split_string(css_contents, 2, max_selectors)
100
+ end
101
+
102
+ test '#split_string where the media part would overlap the split, no rules in media before the split' do
103
+ # This tests the following situation:
104
+ # Part 1: CssSplitter::Splitter::MAX_SELECTORS_DEFAULT
105
+ # Part 2: Opens with media block with 1 rule inside and one after
106
+
107
+ # Change this line to any number, for example 4, if it fails to ease debugging
108
+ max_selectors = CssSplitter::Splitter::MAX_SELECTORS_DEFAULT
109
+
110
+ css_rules = []
111
+ max_selectors.times do |n|
112
+ css_rules << ".a#{n} { color: black; }"
113
+ end
114
+ media_rule = "@media only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 768px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 1280px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 800px) {"
115
+ last_part = "#{media_rule} .first-in-media-after-split { color: black; } } .first-after-media { color: black; }"
116
+
117
+ first_contents = css_rules.join("").gsub(/\s/, '')
118
+ last_contents = last_part.gsub(/\s/, '')
119
+ css_contents = "#{first_contents}#{last_contents}"
120
+
121
+ assert_equal first_contents, CssSplitter::Splitter.split_string(css_contents, 1, max_selectors)
122
+ assert_equal last_contents, CssSplitter::Splitter.split_string(css_contents, 2, max_selectors)
123
+ end
124
+
125
+ test '#split_string where the media part would overlap the split, with rules in media before the split' do
126
+ # This tests the following situation:
127
+ # Part 1: CssSplitter::Splitter::MAX_SELECTORS_DEFAULT - 1 rules
128
+ # + Media block and first rule inside the media block
129
+ # Part 2: Opens with media block with last rule inside and one after
130
+
131
+ # Change this line to any number, for example 4, if it fails to ease debugging
132
+ max_selectors = CssSplitter::Splitter::MAX_SELECTORS_DEFAULT
133
+
134
+ css_rules = []
135
+ (max_selectors - 1).times do |n|
136
+ css_rules << ".a#{n} { color: black; }"
137
+ end
138
+ css_rules << media_rule = "@media only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 768px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 1280px), only screen and (-webkit-min-device-pixel-ratio: 0) and (device-width: 800px) {"
139
+ css_rules << ".last-before-split { color: black; }"
140
+
141
+ after_split = ".last-after-split { color: black; } } .first-after-media { color: black; }".gsub(/\s/, '')
142
+
143
+ first_contents = css_rules.join("").gsub(/\s/, '')
144
+ css_contents = "#{first_contents}#{after_split}"
145
+
146
+ # The last part should open with the media, followed by the rules defined in after_split
147
+ last_contents = "#{media_rule}#{after_split}".gsub(/\s/, '')
148
+
149
+ # The first file should be closed neatly, as the media part opened before the last rule
150
+ # it should be closed as well.
151
+ assert_equal "#{first_contents}}", CssSplitter::Splitter.split_string(css_contents, 1, max_selectors)
152
+
153
+ # The second part should open with the media definition, followed by one rule inside
154
+ # the media block and one rule after.
155
+ assert_equal last_contents, CssSplitter::Splitter.split_string(css_contents, 2, max_selectors)
156
+ end
157
+
158
+ test '#split_string where the media part comes before the split' do
159
+ # This tests the following situation:
160
+ # Part 1: Media block with rule inside media block
161
+ # + CssSplitter::Splitter::MAX_SELECTORS_DEFAULT - 1 rules outside media block
162
+ # Part 2: Outputs the last rule outside media block
163
+
164
+ # Change this line to any number, for example 4, if it fails to ease debugging
165
+ max_selectors = CssSplitter::Splitter::MAX_SELECTORS_DEFAULT
166
+
167
+ css_rules = []
168
+ css_rules << "@media print { .media-rule { color: black; } }"
169
+
170
+ (max_selectors - 1).times do |n|
171
+ css_rules << ".a#{n} { color: black; }"
172
+ end
173
+
174
+ first_contents = css_rules.join("").gsub(/\s/, '')
175
+ last_contents = ".first-after-split { color: black; }".gsub(/\s/, '')
176
+
177
+ css_contents = "#{first_contents}#{last_contents}"
178
+
179
+ assert_equal first_contents, CssSplitter::Splitter.split_string(css_contents, 1, max_selectors)
180
+ assert_equal last_contents, CssSplitter::Splitter.split_string(css_contents, 2, max_selectors)
181
+ end
182
+
183
+ # --- strip_comments ---
184
+
185
+ test '#strip_comments: strip single line CSS coment' do
186
+ assert_equal ".foo { color: black; }\n.foo { color: black; }", CssSplitter::Splitter.send(:strip_comments, ".foo { color: black; }\n/* comment */.foo { color: black; }")
187
+ end
188
+
189
+ test '#strip_comments: strip multiline CSS coment' do
190
+ assert_equal ".foo { color: black; }\n.foo { color: black; }", CssSplitter::Splitter.send(:strip_comments, ".foo { color: black; }\n/* multi\nline\ncomment */.foo { color: black; }")
191
+ end
192
+ end