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.
- checksums.yaml +7 -0
- data/.yardopts +13 -0
- data/AGENTS.md +534 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +148 -0
- data/MIT-LICENSE +20 -0
- data/README.md +242 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/sass +13 -0
- data/bin/sass-convert +12 -0
- data/bin/scss +13 -0
- data/extra/sass-spec-ref.sh +40 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +18 -0
- data/lib/sass/cache_stores/base.rb +88 -0
- data/lib/sass/cache_stores/chain.rb +34 -0
- data/lib/sass/cache_stores/filesystem.rb +60 -0
- data/lib/sass/cache_stores/memory.rb +46 -0
- data/lib/sass/cache_stores/null.rb +25 -0
- data/lib/sass/cache_stores.rb +15 -0
- data/lib/sass/callbacks.rb +67 -0
- data/lib/sass/css.rb +407 -0
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +1236 -0
- data/lib/sass/environment.rb +236 -0
- data/lib/sass/error.rb +198 -0
- data/lib/sass/exec/base.rb +188 -0
- data/lib/sass/exec/sass_convert.rb +283 -0
- data/lib/sass/exec/sass_scss.rb +436 -0
- data/lib/sass/exec.rb +9 -0
- data/lib/sass/features.rb +48 -0
- data/lib/sass/importers/base.rb +182 -0
- data/lib/sass/importers/deprecated_path.rb +51 -0
- data/lib/sass/importers/filesystem.rb +221 -0
- data/lib/sass/importers.rb +23 -0
- data/lib/sass/logger/base.rb +47 -0
- data/lib/sass/logger/delayed.rb +50 -0
- data/lib/sass/logger/log_level.rb +45 -0
- data/lib/sass/logger.rb +17 -0
- data/lib/sass/media.rb +210 -0
- data/lib/sass/plugin/compiler.rb +552 -0
- data/lib/sass/plugin/configuration.rb +134 -0
- data/lib/sass/plugin/generic.rb +15 -0
- data/lib/sass/plugin/merb.rb +48 -0
- data/lib/sass/plugin/rack.rb +60 -0
- data/lib/sass/plugin/rails.rb +47 -0
- data/lib/sass/plugin/staleness_checker.rb +199 -0
- data/lib/sass/plugin.rb +134 -0
- data/lib/sass/railtie.rb +10 -0
- data/lib/sass/repl.rb +57 -0
- data/lib/sass/root.rb +7 -0
- data/lib/sass/script/css_lexer.rb +33 -0
- data/lib/sass/script/css_parser.rb +36 -0
- data/lib/sass/script/functions.rb +3103 -0
- data/lib/sass/script/lexer.rb +518 -0
- data/lib/sass/script/parser.rb +1164 -0
- data/lib/sass/script/tree/funcall.rb +314 -0
- data/lib/sass/script/tree/interpolation.rb +220 -0
- data/lib/sass/script/tree/list_literal.rb +119 -0
- data/lib/sass/script/tree/literal.rb +49 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/tree/node.rb +119 -0
- data/lib/sass/script/tree/operation.rb +149 -0
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +125 -0
- data/lib/sass/script/tree/unary_operation.rb +69 -0
- data/lib/sass/script/tree/variable.rb +57 -0
- data/lib/sass/script/tree.rb +16 -0
- data/lib/sass/script/value/arg_list.rb +36 -0
- data/lib/sass/script/value/base.rb +258 -0
- data/lib/sass/script/value/bool.rb +35 -0
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +704 -0
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +298 -0
- data/lib/sass/script/value/list.rb +135 -0
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/null.rb +44 -0
- data/lib/sass/script/value/number.rb +564 -0
- data/lib/sass/script/value/string.rb +138 -0
- data/lib/sass/script/value.rb +13 -0
- data/lib/sass/script.rb +66 -0
- data/lib/sass/scss/css_parser.rb +61 -0
- data/lib/sass/scss/parser.rb +1343 -0
- data/lib/sass/scss/rx.rb +134 -0
- data/lib/sass/scss/static_parser.rb +351 -0
- data/lib/sass/scss.rb +14 -0
- data/lib/sass/selector/abstract_sequence.rb +112 -0
- data/lib/sass/selector/comma_sequence.rb +195 -0
- data/lib/sass/selector/pseudo.rb +291 -0
- data/lib/sass/selector/sequence.rb +661 -0
- data/lib/sass/selector/simple.rb +124 -0
- data/lib/sass/selector/simple_sequence.rb +348 -0
- data/lib/sass/selector.rb +327 -0
- data/lib/sass/shared.rb +76 -0
- data/lib/sass/source/map.rb +209 -0
- data/lib/sass/source/position.rb +39 -0
- data/lib/sass/source/range.rb +41 -0
- data/lib/sass/stack.rb +140 -0
- data/lib/sass/supports.rb +225 -0
- data/lib/sass/tree/at_root_node.rb +83 -0
- data/lib/sass/tree/charset_node.rb +22 -0
- data/lib/sass/tree/comment_node.rb +82 -0
- data/lib/sass/tree/content_node.rb +9 -0
- data/lib/sass/tree/css_import_node.rb +68 -0
- data/lib/sass/tree/debug_node.rb +18 -0
- data/lib/sass/tree/directive_node.rb +59 -0
- data/lib/sass/tree/each_node.rb +24 -0
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +43 -0
- data/lib/sass/tree/for_node.rb +36 -0
- data/lib/sass/tree/function_node.rb +44 -0
- data/lib/sass/tree/if_node.rb +52 -0
- data/lib/sass/tree/import_node.rb +75 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/media_node.rb +48 -0
- data/lib/sass/tree/mixin_def_node.rb +38 -0
- data/lib/sass/tree/mixin_node.rb +52 -0
- data/lib/sass/tree/node.rb +240 -0
- data/lib/sass/tree/prop_node.rb +162 -0
- data/lib/sass/tree/return_node.rb +19 -0
- data/lib/sass/tree/root_node.rb +44 -0
- data/lib/sass/tree/rule_node.rb +153 -0
- data/lib/sass/tree/supports_node.rb +38 -0
- data/lib/sass/tree/trace_node.rb +33 -0
- data/lib/sass/tree/variable_node.rb +36 -0
- data/lib/sass/tree/visitors/base.rb +72 -0
- data/lib/sass/tree/visitors/check_nesting.rb +173 -0
- data/lib/sass/tree/visitors/convert.rb +350 -0
- data/lib/sass/tree/visitors/cssize.rb +362 -0
- data/lib/sass/tree/visitors/deep_copy.rb +107 -0
- data/lib/sass/tree/visitors/extend.rb +64 -0
- data/lib/sass/tree/visitors/perform.rb +572 -0
- data/lib/sass/tree/visitors/set_options.rb +139 -0
- data/lib/sass/tree/visitors/to_css.rb +440 -0
- data/lib/sass/tree/warn_node.rb +18 -0
- data/lib/sass/tree/while_node.rb +18 -0
- data/lib/sass/util/multibyte_string_scanner.rb +151 -0
- data/lib/sass/util/normalized_map.rb +122 -0
- data/lib/sass/util/subset_map.rb +109 -0
- data/lib/sass/util/test.rb +9 -0
- data/lib/sass/util.rb +1137 -0
- data/lib/sass/version.rb +120 -0
- data/lib/sass.rb +102 -0
- data/rails/init.rb +1 -0
- 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.
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -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
|