sass4 4.0.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 (147) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +13 -0
  3. data/AGENTS.md +534 -0
  4. data/CODE_OF_CONDUCT.md +10 -0
  5. data/CONTRIBUTING.md +148 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +242 -0
  8. data/VERSION +1 -0
  9. data/VERSION_NAME +1 -0
  10. data/bin/sass +13 -0
  11. data/bin/sass-convert +12 -0
  12. data/bin/scss +13 -0
  13. data/extra/sass-spec-ref.sh +40 -0
  14. data/extra/update_watch.rb +13 -0
  15. data/init.rb +18 -0
  16. data/lib/sass/cache_stores/base.rb +88 -0
  17. data/lib/sass/cache_stores/chain.rb +34 -0
  18. data/lib/sass/cache_stores/filesystem.rb +60 -0
  19. data/lib/sass/cache_stores/memory.rb +46 -0
  20. data/lib/sass/cache_stores/null.rb +25 -0
  21. data/lib/sass/cache_stores.rb +15 -0
  22. data/lib/sass/callbacks.rb +67 -0
  23. data/lib/sass/css.rb +407 -0
  24. data/lib/sass/deprecation.rb +55 -0
  25. data/lib/sass/engine.rb +1236 -0
  26. data/lib/sass/environment.rb +236 -0
  27. data/lib/sass/error.rb +198 -0
  28. data/lib/sass/exec/base.rb +188 -0
  29. data/lib/sass/exec/sass_convert.rb +283 -0
  30. data/lib/sass/exec/sass_scss.rb +436 -0
  31. data/lib/sass/exec.rb +9 -0
  32. data/lib/sass/features.rb +48 -0
  33. data/lib/sass/importers/base.rb +182 -0
  34. data/lib/sass/importers/deprecated_path.rb +51 -0
  35. data/lib/sass/importers/filesystem.rb +221 -0
  36. data/lib/sass/importers.rb +23 -0
  37. data/lib/sass/logger/base.rb +47 -0
  38. data/lib/sass/logger/delayed.rb +50 -0
  39. data/lib/sass/logger/log_level.rb +45 -0
  40. data/lib/sass/logger.rb +17 -0
  41. data/lib/sass/media.rb +210 -0
  42. data/lib/sass/plugin/compiler.rb +552 -0
  43. data/lib/sass/plugin/configuration.rb +134 -0
  44. data/lib/sass/plugin/generic.rb +15 -0
  45. data/lib/sass/plugin/merb.rb +48 -0
  46. data/lib/sass/plugin/rack.rb +60 -0
  47. data/lib/sass/plugin/rails.rb +47 -0
  48. data/lib/sass/plugin/staleness_checker.rb +199 -0
  49. data/lib/sass/plugin.rb +134 -0
  50. data/lib/sass/railtie.rb +10 -0
  51. data/lib/sass/repl.rb +57 -0
  52. data/lib/sass/root.rb +7 -0
  53. data/lib/sass/script/css_lexer.rb +33 -0
  54. data/lib/sass/script/css_parser.rb +36 -0
  55. data/lib/sass/script/functions.rb +3103 -0
  56. data/lib/sass/script/lexer.rb +518 -0
  57. data/lib/sass/script/parser.rb +1164 -0
  58. data/lib/sass/script/tree/funcall.rb +314 -0
  59. data/lib/sass/script/tree/interpolation.rb +220 -0
  60. data/lib/sass/script/tree/list_literal.rb +119 -0
  61. data/lib/sass/script/tree/literal.rb +49 -0
  62. data/lib/sass/script/tree/map_literal.rb +64 -0
  63. data/lib/sass/script/tree/node.rb +119 -0
  64. data/lib/sass/script/tree/operation.rb +149 -0
  65. data/lib/sass/script/tree/selector.rb +26 -0
  66. data/lib/sass/script/tree/string_interpolation.rb +125 -0
  67. data/lib/sass/script/tree/unary_operation.rb +69 -0
  68. data/lib/sass/script/tree/variable.rb +57 -0
  69. data/lib/sass/script/tree.rb +16 -0
  70. data/lib/sass/script/value/arg_list.rb +36 -0
  71. data/lib/sass/script/value/base.rb +258 -0
  72. data/lib/sass/script/value/bool.rb +35 -0
  73. data/lib/sass/script/value/callable.rb +25 -0
  74. data/lib/sass/script/value/color.rb +704 -0
  75. data/lib/sass/script/value/function.rb +19 -0
  76. data/lib/sass/script/value/helpers.rb +298 -0
  77. data/lib/sass/script/value/list.rb +135 -0
  78. data/lib/sass/script/value/map.rb +70 -0
  79. data/lib/sass/script/value/null.rb +44 -0
  80. data/lib/sass/script/value/number.rb +564 -0
  81. data/lib/sass/script/value/string.rb +138 -0
  82. data/lib/sass/script/value.rb +13 -0
  83. data/lib/sass/script.rb +66 -0
  84. data/lib/sass/scss/css_parser.rb +61 -0
  85. data/lib/sass/scss/parser.rb +1343 -0
  86. data/lib/sass/scss/rx.rb +134 -0
  87. data/lib/sass/scss/static_parser.rb +351 -0
  88. data/lib/sass/scss.rb +14 -0
  89. data/lib/sass/selector/abstract_sequence.rb +112 -0
  90. data/lib/sass/selector/comma_sequence.rb +195 -0
  91. data/lib/sass/selector/pseudo.rb +291 -0
  92. data/lib/sass/selector/sequence.rb +661 -0
  93. data/lib/sass/selector/simple.rb +124 -0
  94. data/lib/sass/selector/simple_sequence.rb +348 -0
  95. data/lib/sass/selector.rb +327 -0
  96. data/lib/sass/shared.rb +76 -0
  97. data/lib/sass/source/map.rb +209 -0
  98. data/lib/sass/source/position.rb +39 -0
  99. data/lib/sass/source/range.rb +41 -0
  100. data/lib/sass/stack.rb +140 -0
  101. data/lib/sass/supports.rb +225 -0
  102. data/lib/sass/tree/at_root_node.rb +83 -0
  103. data/lib/sass/tree/charset_node.rb +22 -0
  104. data/lib/sass/tree/comment_node.rb +82 -0
  105. data/lib/sass/tree/content_node.rb +9 -0
  106. data/lib/sass/tree/css_import_node.rb +68 -0
  107. data/lib/sass/tree/debug_node.rb +18 -0
  108. data/lib/sass/tree/directive_node.rb +59 -0
  109. data/lib/sass/tree/each_node.rb +24 -0
  110. data/lib/sass/tree/error_node.rb +18 -0
  111. data/lib/sass/tree/extend_node.rb +43 -0
  112. data/lib/sass/tree/for_node.rb +36 -0
  113. data/lib/sass/tree/function_node.rb +44 -0
  114. data/lib/sass/tree/if_node.rb +52 -0
  115. data/lib/sass/tree/import_node.rb +75 -0
  116. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  117. data/lib/sass/tree/media_node.rb +48 -0
  118. data/lib/sass/tree/mixin_def_node.rb +38 -0
  119. data/lib/sass/tree/mixin_node.rb +52 -0
  120. data/lib/sass/tree/node.rb +240 -0
  121. data/lib/sass/tree/prop_node.rb +162 -0
  122. data/lib/sass/tree/return_node.rb +19 -0
  123. data/lib/sass/tree/root_node.rb +44 -0
  124. data/lib/sass/tree/rule_node.rb +153 -0
  125. data/lib/sass/tree/supports_node.rb +38 -0
  126. data/lib/sass/tree/trace_node.rb +33 -0
  127. data/lib/sass/tree/variable_node.rb +36 -0
  128. data/lib/sass/tree/visitors/base.rb +72 -0
  129. data/lib/sass/tree/visitors/check_nesting.rb +173 -0
  130. data/lib/sass/tree/visitors/convert.rb +350 -0
  131. data/lib/sass/tree/visitors/cssize.rb +362 -0
  132. data/lib/sass/tree/visitors/deep_copy.rb +107 -0
  133. data/lib/sass/tree/visitors/extend.rb +64 -0
  134. data/lib/sass/tree/visitors/perform.rb +572 -0
  135. data/lib/sass/tree/visitors/set_options.rb +139 -0
  136. data/lib/sass/tree/visitors/to_css.rb +440 -0
  137. data/lib/sass/tree/warn_node.rb +18 -0
  138. data/lib/sass/tree/while_node.rb +18 -0
  139. data/lib/sass/util/multibyte_string_scanner.rb +151 -0
  140. data/lib/sass/util/normalized_map.rb +122 -0
  141. data/lib/sass/util/subset_map.rb +109 -0
  142. data/lib/sass/util/test.rb +9 -0
  143. data/lib/sass/util.rb +1137 -0
  144. data/lib/sass/version.rb +120 -0
  145. data/lib/sass.rb +102 -0
  146. data/rails/init.rb +1 -0
  147. metadata +283 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8746113a3c93d6763ffc657134bae7c7bc885d8fe3ec2f78f98e7c6a41d75f33
4
+ data.tar.gz: 110c8380a322ac19911e21e41a9a3ec9ec192c927cf1f6eebc8078edfbb06868
5
+ SHA512:
6
+ metadata.gz: 744b963c9ba12ed8b392fa17fa170cc28478024b54d5bcaff1998c3f4f8d5a91195ff1c069ff5ce862b175f55790683a04506e6f5822fcff66f2dacc20cccfe4
7
+ data.tar.gz: 79c29d4de8f0d6221dd934d349f8b141a009e9afd6fd54efb1d5a817a8652b39c5d6eeb8306dfa5c305d3815cf5e10d3e7bd18a0afb448575b403f8950141636
data/.yardopts ADDED
@@ -0,0 +1,13 @@
1
+ --readme README.md
2
+ --markup markdown
3
+ --markup-provider redcarpet
4
+ --default-return ""
5
+ --title "Sass Documentation"
6
+ --query 'object.type != :classvariable'
7
+ --query 'object.type != :constant || @api && @api.text == "public"'
8
+ --hide-void-return
9
+ --protected
10
+ --no-private
11
+ --no-highlight
12
+ --tag comment
13
+ --hide-tag comment
data/AGENTS.md ADDED
@@ -0,0 +1,534 @@
1
+ # AGENTS.md - Ruby Sass Project Guide
2
+
3
+ ## Обзор проекта
4
+
5
+ **Ruby Sass** - это оригинальная реализация препроцессора CSS Sass на Ruby. Проект достиг конца жизненного цикла (end-of-life) и больше не поддерживается. Рекомендуется использовать Dart Sass или sassc gem.
6
+
7
+ **Версия:** 3.7.4.7a50eae
8
+ **Лицензия:** MIT
9
+ **Статус:** End-of-life (не рекомендуется к использованию)
10
+
11
+ ## Архитектура проекта
12
+
13
+ ### Основные компоненты
14
+
15
+ ```
16
+ lib/sass/
17
+ ├── engine.rb # Основной движок компиляции
18
+ ├── tree/ # AST (Abstract Syntax Tree) узлы
19
+ │ ├── node.rb # Базовый класс для всех узлов
20
+ │ ├── import_node.rb # Обработка @import директив
21
+ │ ├── if_node.rb # Обработка @if/@else директив
22
+ │ ├── rule_node.rb # CSS правила
23
+ │ └── visitors/ # Паттерн Visitor для обхода AST
24
+ │ ├── perform.rb # Выполнение динамических узлов
25
+ │ ├── convert.rb # Конвертация в исходный код
26
+ │ └── to_css.rb # Генерация CSS
27
+ ├── script/ # SassScript (выражения и функции)
28
+ ├── scss/ # SCSS парсер
29
+ ├── importers/ # Система импорта файлов
30
+ ├── cache_stores/ # Кэширование
31
+ └── plugin/ # Интеграции с фреймворками
32
+ ```
33
+
34
+ ### Ключевые классы
35
+
36
+ - **Sass::Engine** - основной класс для компиляции Sass/SCSS
37
+ - **Sass::Tree::Node** - базовый класс для всех AST узлов
38
+ - **Sass::Tree::Visitors::Perform** - visitor для выполнения динамических операций
39
+ - **Sass::Tree::Visitors::ToCss** - visitor для генерации CSS
40
+ - **Sass::Importers::Filesystem** - импортер файлов из файловой системы
41
+
42
+ ## Тестовая структура
43
+
44
+ ### Организация тестов
45
+
46
+ Проект использует **Minitest** как основной фреймворк тестирования с двумя типами тестов:
47
+
48
+ 1. **Ruby тесты** (`test:ruby`) - внутренние тесты проекта
49
+ 2. **Sass-spec тесты** (`test:spec`) - тесты из официальной спецификации
50
+
51
+ ### Структура тестов
52
+
53
+ ```
54
+ test/
55
+ ├── test_helper.rb # Общие утилиты для тестов
56
+ ├── sass/
57
+ │ ├── engine_test.rb # Основные тесты движка (1500+ тестов)
58
+ │ ├── templates/ # Sass/SCSS файлы для тестирования
59
+ │ │ ├── basic.sass # Базовые тесты
60
+ │ │ ├── import.sass # Тесты импорта
61
+ │ │ ├── if.sass # Тесты условных директив
62
+ │ │ ├── nested.sass # Тесты вложенности
63
+ │ │ └── ...
64
+ │ ├── results/ # Ожидаемые CSS результаты
65
+ │ │ ├── basic.css
66
+ │ │ ├── import.css
67
+ │ │ └── ...
68
+ │ ├── cache_test.rb # Тесты кэширования
69
+ │ ├── functions_test.rb # Тесты встроенных функций
70
+ │ ├── importer_test.rb # Тесты системы импорта
71
+ │ └── util/ # Тесты утилит
72
+ ```
73
+
74
+ ### Типы тестов
75
+
76
+ #### 1. Функциональные тесты (engine_test.rb)
77
+ - **1500+ тестов** покрывающих все аспекты компиляции
78
+ - Тестирование синтаксиса Sass и SCSS
79
+ - Проверка обработки ошибок
80
+ - Тесты производительности
81
+
82
+ #### 2. Тесты на основе файлов
83
+ ```ruby
84
+ def renders_correctly(name, options={})
85
+ sass_file = load_file(name, "sass")
86
+ css_file = load_file(name, "css")
87
+ css_result = Sass::Engine.new(sass_file, options).render
88
+ assert_equal css_file, css_result
89
+ end
90
+ ```
91
+
92
+ #### 3. Тесты импорта
93
+ ```ruby
94
+ def test_import_in_rule
95
+ assert_equal(<<CSS, render(<<SASS, :load_paths => [File.dirname(__FILE__) + '/templates/']))
96
+ .foo #foo {
97
+ background-color: #baf; }
98
+ CSS
99
+ .foo
100
+ @import partial
101
+ SASS
102
+ end
103
+ ```
104
+
105
+ ### Запуск тестов
106
+
107
+ лучше запускать тесты через rake
108
+
109
+ ```bash
110
+ # Все тесты
111
+ bundle exec rake test
112
+
113
+ # Только Ruby тесты
114
+ bundle exec rake test:ruby
115
+
116
+ # Только Sass-spec тесты
117
+ bundle exec rake test:spec
118
+
119
+ # Конкретный тест
120
+ ruby -Ilib:test test/sass/engine_test.rb -n test_import_in_rule
121
+ ```
122
+
123
+ ### Тестовые утилиты
124
+
125
+ #### test_helper.rb предоставляет:
126
+
127
+ ```ruby
128
+ # Проверка преобразований
129
+ def assert_converts(sass, scss, options: {})
130
+ assert_sass_to_sass(sass, options: options)
131
+ assert_scss_to_sass(sass, scss, options: options)
132
+ assert_scss_to_scss(scss, options: options)
133
+ assert_sass_to_scss(scss, sass, options: options)
134
+ end
135
+
136
+ # Проверка предупреждений
137
+ def assert_warning(message)
138
+ # Перехватывает stderr и проверяет сообщения
139
+ end
140
+
141
+ # Проверка исключений
142
+ def assert_raise_message(klass, message)
143
+ # Проверяет тип и сообщение исключения
144
+ end
145
+ ```
146
+
147
+ ## Ключевые области для тестирования
148
+
149
+ ### 1. Парсинг и AST
150
+ - **Файлы:** `scss/parser.rb`, `script/parser.rb`
151
+ - **Тесты:** `scss_test.rb`, `script_test.rb`
152
+ - **Фокус:** Корректность парсинга различных конструкций
153
+
154
+ ### 2. Система импорта
155
+ - **Файлы:** `importers/`, `tree/import_node.rb`
156
+ - **Тесты:** `importer_test.rb`, тесты в `engine_test.rb`
157
+ - **Фокус:** Разрешение путей, кэширование, циклические зависимости
158
+
159
+ ### 3. Выполнение SassScript
160
+ - **Файлы:** `script/`, `tree/visitors/perform.rb`
161
+ - **Тесты:** `script_test.rb`, `functions_test.rb`
162
+ - **Фокус:** Математические операции, функции, переменные
163
+
164
+ ### 4. Генерация CSS
165
+ - **Файлы:** `tree/visitors/to_css.rb`
166
+ - **Тесты:** Все тесты в `templates/` и `results/`
167
+ - **Фокус:** Корректность вывода CSS
168
+
169
+ ### 5. Кэширование
170
+ - **Файлы:** `cache_stores/`
171
+ - **Тесты:** `cache_test.rb`
172
+ - **Фокус:** Производительность, инвалидация кэша
173
+
174
+ ## Паттерны тестирования
175
+
176
+ ### 1. Тестирование на основе файлов
177
+ ```ruby
178
+ # templates/test.sass -> results/test.css
179
+ def test_basic
180
+ renders_correctly "basic"
181
+ end
182
+ ```
183
+
184
+ ### 2. Inline тестирование
185
+ ```ruby
186
+ def test_variables
187
+ assert_equal(<<CSS, render(<<SASS))
188
+ .foo {
189
+ color: red; }
190
+ CSS
191
+ $color: red
192
+ .foo
193
+ color: $color
194
+ SASS
195
+ end
196
+ ```
197
+
198
+ ### 3. Тестирование ошибок
199
+ ```ruby
200
+ def test_invalid_syntax
201
+ assert_raise_message(Sass::SyntaxError, "Invalid property") do
202
+ render("invalid: syntax")
203
+ end
204
+ end
205
+ ```
206
+
207
+ ### 4. Тестирование предупреждений
208
+ ```ruby
209
+ def test_deprecation_warning
210
+ assert_warning(/deprecated/) do
211
+ render("deprecated-feature")
212
+ end
213
+ end
214
+ ```
215
+
216
+ ## Особенности тестирования
217
+
218
+ ### 1. Поддержка двух синтаксисов
219
+ Все тесты должны работать как для Sass, так и для SCSS:
220
+ ```ruby
221
+ def assert_converts(sass, scss, options: {})
222
+ # Проверяет преобразования в обе стороны
223
+ end
224
+ ```
225
+
226
+ ### 2. Тестирование с разными опциями
227
+ ```ruby
228
+ def test_with_options
229
+ assert_equal(expected, render(input, :style => :compressed))
230
+ end
231
+ ```
232
+
233
+ ### 3. Mock импортеры
234
+ ```ruby
235
+ # test/sass/mock_importer.rb
236
+ class MockImporter < Sass::Importers::Base
237
+ def add_import(name, content)
238
+ # Добавляет виртуальные файлы для тестирования
239
+ end
240
+ end
241
+ ```
242
+
243
+ ## Рекомендации для разработчиков
244
+
245
+ ### 1. При добавлении новых функций
246
+ - Добавить тесты в `functions_test.rb`
247
+ - Обновить документацию
248
+ - Проверить совместимость с Sass-spec
249
+
250
+ ### 2. При изменении парсера
251
+ - Добавить тесты в соответствующие `*_test.rb` файлы
252
+ - Проверить обработку ошибок
253
+ - Убедиться в обратной совместимости
254
+
255
+ ### 3. При оптимизации производительности
256
+ - Добавить бенчмарки в тесты
257
+ - Проверить кэширование
258
+ - Убедиться в корректности результатов
259
+
260
+ ### 4. При исправлении багов
261
+ - Создать минимальный тест, воспроизводящий баг
262
+ - Добавить регрессионный тест
263
+ - Проверить edge cases
264
+
265
+ ## Инструменты разработки
266
+
267
+ ### 1. Rake задачи
268
+ ```bash
269
+ rake test # Все тесты
270
+ rake test:ruby # Ruby тесты
271
+ rake test:spec # Sass-spec тесты
272
+ rake package # Сборка gem
273
+ ```
274
+
275
+ ### 2. Отладка
276
+ ```ruby
277
+ # Включение трассировки селекторов
278
+ options[:trace_selectors] = true
279
+
280
+ # Включение отладочной информации
281
+ options[:debug_info] = true
282
+ ```
283
+
284
+ ### 3. Профилирование
285
+ ```ruby
286
+ # Измерение времени выполнения
287
+ require 'benchmark'
288
+ Benchmark.measure { engine.render }
289
+ ```
290
+
291
+ ## Запуск тестов
292
+
293
+ ### Требования к системе
294
+
295
+ **Ruby**: >= 3.0.0 (рекомендуется Ruby 3.1.2+)
296
+
297
+ Файлы для управления версиями Ruby:
298
+ - `.ruby-version` - указывает версию Ruby (3.1.2)
299
+ - `.ruby-gemset` - указывает gemset для RVM (ruby-sass)
300
+
301
+ ### Обновленные зависимости
302
+
303
+ Проект был обновлен для совместимости с Ruby 3.1+:
304
+
305
+ - **Rake**: ~> 13.0
306
+ - **Minitest**: ~> 5.20
307
+ - **Nokogiri**: ~> 1.15.0
308
+ - **YARD**: ~> 0.9.0
309
+ - **Redcarpet**: ~> 3.6.0
310
+
311
+ ### Проблемы с зависимостями (решенные)
312
+
313
+ 1. ✅ **MiniTest vs Minitest**: Исправлено во всех тестовых файлах
314
+ 2. ✅ **Nokogiri**: Обновлен до версии 1.15.0
315
+ 3. ⚠️ **Sass-spec**: Проблемы с ruby-terminfo, временно отключен
316
+
317
+ ### Решение проблем
318
+
319
+ #### 1. Исправление test_helper.rb
320
+ ```ruby
321
+ # В test/test_helper.rb заменить:
322
+ class MiniTest::Test
323
+ # На:
324
+ class Minitest::Test
325
+ ```
326
+
327
+ #### 2. Настройка окружения
328
+ ```bash
329
+ # Если используете RVM
330
+ rvm use 3.1.2
331
+ rvm gemset create ruby-sass
332
+ rvm gemset use ruby-sass
333
+
334
+ # Если используете rbenv
335
+ rbenv install 3.1.2
336
+ rbenv local 3.1.2
337
+
338
+ # Установка зависимостей
339
+ bundle install
340
+ ```
341
+
342
+ #### 3. Запуск тестов
343
+ ```bash
344
+ # Запуск всех Ruby тестов (2122 теста)
345
+ bundle exec rake test:ruby
346
+
347
+ # Запуск конкретного теста
348
+ bundle exec ruby -Ilib:test test/sass/css_level4_selectors_test.rb
349
+
350
+ # Запуск всех тестов (включая sass-spec, если доступен)
351
+ bundle exec rake test
352
+ ```
353
+
354
+ #### 4. Установка sass-spec по тегу
355
+ Для работы с sass-spec можно использовать тег v3.5.4, который соответствует версии Ruby Sass:
356
+
357
+ ```ruby
358
+ # В Gemfile
359
+ gem "sass-spec", :git => 'https://github.com/sass/sass-spec.git', :tag => 'v3.5.4'
360
+ ```
361
+
362
+ #### 5. Создание простых тестов
363
+ Для избежания проблем с зависимостями можно создавать простые тесты без minitest/autorun:
364
+
365
+ ```ruby
366
+ #!/usr/bin/env ruby
367
+ require_relative '../../lib/sass'
368
+
369
+ class MyTest
370
+ def test_something
371
+ # Ваш тест
372
+ result = Sass::Engine.new("body { color: red; }").render
373
+ assert_equal "body {\n color: red; }\n", result
374
+ end
375
+
376
+ def assert_equal(expected, actual, message = nil)
377
+ unless expected == actual
378
+ raise "#{message || 'Assertion failed'}: expected '#{expected}', got '#{actual}'"
379
+ end
380
+ end
381
+
382
+ def run_all_tests
383
+ # Логика запуска всех тестов
384
+ end
385
+ end
386
+
387
+ if __FILE__ == $0
388
+ test = MyTest.new
389
+ test.run_all_tests
390
+ end
391
+ ```
392
+
393
+ ### Структура тестов
394
+
395
+ ```
396
+ test/
397
+ ├── test_helper.rb # Общие утилиты (требует исправления)
398
+ ├── sass/
399
+ │ ├── engine_test.rb # Основные тесты движка
400
+ │ ├── css_level4_selectors_test.rb # Тесты CSS Level 4 селекторов
401
+ │ └── ...
402
+ ```
403
+
404
+ ### Рекомендации
405
+
406
+ 1. **Для новых тестов**: Используйте простую структуру без minitest/autorun
407
+ 2. **Для существующих тестов**: Исправьте test_helper.rb и запускайте через `ruby -Ilib:test`
408
+ 3. **Для полного тестирования**: Обновите зависимости или используйте Docker с совместимой версией Ruby
409
+
410
+ ## Реализация CSS Color Level 4 синтаксиса
411
+
412
+ ### Обзор задачи
413
+
414
+ Была реализована поддержка CSS Color Level 4 синтаксиса для цветовых функций `rgb()`, `rgba()`, `hsl()`, `hsla()`. Новый синтаксис позволяет использовать:
415
+ - **Space-separated значения**: `rgb(255 0 0)` вместо `rgb(255, 0, 0)`
416
+ - **Slash-separated alpha**: `rgb(255 0 0 / 0.5)` вместо `rgba(255, 0, 0, 0.5)`
417
+
418
+ ### Архитектурное решение
419
+
420
+ #### Проблема
421
+
422
+ Основная проблема заключалась в том, что парсер Ruby Sass интерпретировал символ `/` как оператор деления в выражениях типа `rgb(255 0 0 / 0.5)`, создавая AST структуру `(255 0 (0 / 0.5))` вместо ожидаемой `(255 0 0 / 0.5)`.
423
+
424
+ #### Решение
425
+
426
+ Вместо "костылей" в функциях, было реализовано правильное решение на уровне парсера:
427
+
428
+ 1. **Создан специализированный парсер** `color_fn_arglist` в `lib/sass/script/parser.rb`
429
+ 2. **Модифицирован** метод `funcall` для использования `color_fn_arglist` для функций `rgb/rgba/hsl/hsla`
430
+ 3. **Упрощены** функции цвета в `lib/sass/script/functions.rb` для работы с новой структурой
431
+
432
+ #### Детали реализации
433
+
434
+ ##### 1. Парсер (lib/sass/script/parser.rb)
435
+
436
+ **Метод `funcall`:**
437
+ ```ruby
438
+ def funcall
439
+ tok = try_tok(:funcall)
440
+ return raw unless tok
441
+
442
+ # Специальная обработка для CSS Color Level 4 функций
443
+ if %w[rgb rgba hsl hsla].include?(tok.value.downcase)
444
+ args, keywords, splat, kwarg_splat = color_fn_arglist
445
+ else
446
+ args, keywords, splat, kwarg_splat = fn_arglist
447
+ end
448
+
449
+ assert_tok(:rparen)
450
+ node(Script::Tree::Funcall.new(tok.value, args, keywords, splat, kwarg_splat),
451
+ tok.source_range.start_pos, source_position)
452
+ end
453
+ ```
454
+
455
+ **Метод `color_fn_arglist`:**
456
+ - Парсит аргументы используя `unary_plus` вместо `equals` чтобы избежать интерпретации `/` как деления
457
+ - Определяет тип синтаксиса по следующему токену:
458
+ - `:colon` → keyword arguments (`rgba($color: red, $alpha: 0.5)`)
459
+ - `:comma` → legacy syntax (`rgb(255, 0, 0)`)
460
+ - иначе → CSS Color Level 4 (`rgb(255 0 0)` или `rgb(255 0 0 / 0.5)`)
461
+ - Для CSS Color Level 4 создает специальную структуру:
462
+ - Space-separated список RGB/HSL значений
463
+ - Slash-separated список для alpha (если присутствует)
464
+
465
+ ##### 2. Функции цвета (lib/sass/script/functions.rb)
466
+
467
+ **Структура парсера для `rgb(255 0 0 / 0.5)`:**
468
+ ```ruby
469
+ ListLiteral(space) с 2 элементами:
470
+ [0]: ListLiteral(space) = (255 0 0)
471
+ [1]: ListLiteral(slash) = (0.5)
472
+ ```
473
+
474
+ **Обработка в функции:**
475
+ ```ruby
476
+ def rgb(*args)
477
+ if args.length == 1 && args[0].is_a?(Sass::Script::Value::List)
478
+ list = args[0]
479
+
480
+ if list.separator == :space
481
+ if list.value.length == 3
482
+ # rgb(255 0 0) - без alpha
483
+ red, green, blue = list.value
484
+ return rgb(red, green, blue)
485
+ elsif list.value.length == 2
486
+ # rgb(255 0 0 / 0.5) - с alpha
487
+ rgb_list, alpha_list = list.value
488
+ if rgb_list.separator == :space && alpha_list.separator == :slash
489
+ red, green, blue = rgb_list.value
490
+ alpha = alpha_list.value[0]
491
+ return rgba(red, green, blue, alpha)
492
+ end
493
+ end
494
+ end
495
+ end
496
+
497
+ # Legacy syntax...
498
+ end
499
+ ```
500
+
501
+ ### Результаты тестирования
502
+
503
+ #### Новые тесты
504
+ - ✅ Space-separated без alpha: `rgb(255 0 0)`
505
+ - ✅ Space-separated с процентами: `rgb(0% 100% 0%)`
506
+ - ✅ Slash-separated с alpha: `rgb(255 0 0 / 0.5)`
507
+ - ✅ HSL с углами: `hsl(180deg 60% 50%)`
508
+ - ✅ Переменные: `rgb($r $g $b / $a)`
509
+ - ✅ Alpha как процент: `rgb(255 0 0 / 50%)`
510
+
511
+ #### Обратная совместимость
512
+ - Из 2146 существующих тестов проходит **2133** (99.4%)
513
+ - Все тесты legacy синтаксиса проходят
514
+ - Поддерживаются keyword arguments
515
+ - Незначительные расхождения в форматировании вывода для edge cases
516
+
517
+ ### Ключевые уроки
518
+
519
+ 1. **Правильное решение на уровне парсера** лучше чем "костыли" в функциях
520
+ 2. **Использование приоритета операторов** - парсинг на уровне `unary_plus` вместо `equals` позволяет избежать интерпретации `/` как деления
521
+ 3. **Сохранение обратной совместимости** - важно поддерживать все существующие варианты синтаксиса
522
+
523
+ ### Файлы изменений
524
+
525
+ - `lib/sass/script/parser.rb` - добавлен `color_fn_arglist`, модифицирован `funcall`
526
+ - `lib/sass/script/functions.rb` - обновлены `rgb`, `rgba`, `hsl`, `hsla`
527
+ - `lib/sass/script/tree/list_literal.rb` - добавлена поддержка `:slash` разделителя
528
+ - `lib/sass/script/value/list.rb` - добавлена поддержка `:slash` разделителя
529
+
530
+ ## Заключение
531
+
532
+ Ruby Sass имеет обширную тестовую базу с более чем 1500 тестами, покрывающими все аспекты функциональности. Тесты организованы по функциональным областям и используют как файловые, так и inline подходы. При работе с проектом важно понимать архитектуру AST и паттерн Visitor, а также следовать установленным паттернам тестирования.
533
+
534
+ **Важно:** Проект достиг конца жизненного цикла. Для новых проектов рекомендуется использовать Dart Sass или sassc gem.
@@ -0,0 +1,10 @@
1
+ Sass is more than a technology; Sass is driven by the community of individuals
2
+ that power its development and use every day. As a community, we want to embrace
3
+ the very differences that have made our collaboration so powerful, and work
4
+ together to provide the best environment for learning, growing, and sharing of
5
+ ideas. It is imperative that we keep Sass a fun, welcoming, challenging, and
6
+ fair place to play.
7
+
8
+ [The full community guidelines can be found on the Sass website.][link]
9
+
10
+ [link]: https://sass-lang.com/community-guidelines