2019-04-29 20:27:42 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-04-12 10:52:52 -04:00
|
|
|
require "stylesheet/compiler"
|
|
|
|
|
2022-07-27 22:27:38 -04:00
|
|
|
RSpec.describe Stylesheet::Compiler do
|
2017-07-25 21:49:39 -04:00
|
|
|
describe "compilation" do
|
|
|
|
Dir["#{Rails.root.join("app/assets/stylesheets")}/*.scss"].each do |path|
|
2021-04-29 14:13:36 -04:00
|
|
|
next if path =~ /ember_cli/
|
|
|
|
|
2017-07-25 21:49:39 -04:00
|
|
|
path = File.basename(path, ".scss")
|
|
|
|
|
|
|
|
it "can compile '#{path}' css" do
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset(path)
|
2022-06-21 16:35:46 -04:00
|
|
|
expect(css.length).to be > 500
|
2017-07-25 21:49:39 -04:00
|
|
|
end
|
|
|
|
end
|
2017-04-12 10:52:52 -04:00
|
|
|
end
|
|
|
|
|
2019-09-16 12:06:34 -04:00
|
|
|
context "with a theme" do
|
|
|
|
let!(:theme) { Fabricate(:theme) }
|
2021-02-02 13:09:41 -05:00
|
|
|
let!(:upload) do
|
|
|
|
UploadCreator.new(file_from_fixtures("logo.png"), "logo.png").create_for(
|
|
|
|
Discourse.system_user.id,
|
|
|
|
)
|
2023-01-09 06:18:21 -05:00
|
|
|
end
|
2019-09-16 12:06:34 -04:00
|
|
|
let!(:upload_theme_field) do
|
|
|
|
ThemeField.create!(
|
|
|
|
theme: theme,
|
|
|
|
target_id: 0,
|
|
|
|
name: "primary",
|
|
|
|
upload: upload,
|
|
|
|
value: "",
|
|
|
|
type_id: ThemeField.types[:theme_upload_var],
|
|
|
|
)
|
2023-01-09 06:18:21 -05:00
|
|
|
end
|
2019-09-16 12:06:34 -04:00
|
|
|
let!(:stylesheet_theme_field) do
|
|
|
|
ThemeField.create!(
|
|
|
|
theme: theme,
|
|
|
|
target_id: 0,
|
|
|
|
name: "scss",
|
|
|
|
value: "body { background: $primary }",
|
|
|
|
type_id: ThemeField.types[:scss],
|
|
|
|
)
|
2023-01-09 06:18:21 -05:00
|
|
|
end
|
2019-09-16 12:06:34 -04:00
|
|
|
before { stylesheet_theme_field.save! }
|
|
|
|
|
|
|
|
it "theme stylesheet should be able to access theme asset variables" do
|
2021-02-02 13:09:41 -05:00
|
|
|
css, _map =
|
|
|
|
Stylesheet::Compiler.compile_asset(
|
|
|
|
"desktop_theme",
|
|
|
|
theme_id: theme.id,
|
|
|
|
theme_variables: theme.scss_variables,
|
|
|
|
)
|
2019-09-16 12:06:34 -04:00
|
|
|
expect(css).to include(upload.url)
|
|
|
|
end
|
|
|
|
|
|
|
|
context "with a plugin" do
|
2021-03-15 04:11:23 -04:00
|
|
|
let :plugin1 do
|
2023-06-04 20:06:00 -04:00
|
|
|
plugin1 = plugin_from_fixtures("my_plugin")
|
2021-03-12 11:17:42 -05:00
|
|
|
plugin1.register_css "body { background: $primary }"
|
2021-03-15 04:11:23 -04:00
|
|
|
plugin1
|
|
|
|
end
|
2021-03-12 11:17:42 -05:00
|
|
|
|
2021-03-15 04:11:23 -04:00
|
|
|
let :plugin2 do
|
2023-06-04 20:06:00 -04:00
|
|
|
plugin2 = plugin_from_fixtures("scss_plugin")
|
2021-03-15 04:11:23 -04:00
|
|
|
plugin2
|
|
|
|
end
|
2021-03-12 11:17:42 -05:00
|
|
|
|
2021-03-15 04:11:23 -04:00
|
|
|
before do
|
2021-03-12 11:17:42 -05:00
|
|
|
Discourse.plugins << plugin1
|
|
|
|
Discourse.plugins << plugin2
|
|
|
|
plugin1.activate!
|
|
|
|
plugin2.activate!
|
2019-09-16 12:06:34 -04:00
|
|
|
Stylesheet::Importer.register_imports!
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
2021-03-15 04:11:23 -04:00
|
|
|
Discourse.plugins.delete plugin1
|
|
|
|
Discourse.plugins.delete plugin2
|
2019-09-16 12:06:34 -04:00
|
|
|
Stylesheet::Importer.register_imports!
|
2019-09-20 08:32:43 -04:00
|
|
|
DiscoursePluginRegistry.reset!
|
2019-09-16 12:06:34 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "does not include theme variables in plugins" do
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset("my_plugin", theme_id: theme.id)
|
|
|
|
expect(css).not_to include(upload.url)
|
|
|
|
expect(css).to include("background:")
|
|
|
|
end
|
2021-03-12 11:17:42 -05:00
|
|
|
|
2023-05-31 22:27:11 -04:00
|
|
|
context "with the `rtl` option" do
|
|
|
|
it "generates an RTL version of the plugin CSS if the option is true" do
|
|
|
|
css, _ = Stylesheet::Compiler.compile_asset("scss_plugin", theme_id: theme.id, rtl: true)
|
|
|
|
expect(css).to include(".pull-left{float:right}")
|
|
|
|
expect(css).not_to include(".pull-left{float:left}")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an unchanged version of the plugin CSS" do
|
|
|
|
css, _ = Stylesheet::Compiler.compile_asset("scss_plugin", theme_id: theme.id, rtl: false)
|
|
|
|
expect(css).to include(".pull-left{float:left}")
|
|
|
|
expect(css).not_to include(".pull-left{float:right}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-12 11:17:42 -05:00
|
|
|
it "supports SCSS imports" do
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset("scss_plugin", theme_id: theme.id)
|
|
|
|
|
|
|
|
expect(css).to include("border-color:red")
|
|
|
|
expect(css).to include("fill:green")
|
|
|
|
expect(css).to include("line-height:1.2em")
|
|
|
|
expect(css).to include("border-color:#c00")
|
|
|
|
end
|
2019-09-16 12:06:34 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-04-11 23:57:39 -04:00
|
|
|
it "supports absolute-image-url" do
|
|
|
|
scss = Stylesheet::Importer.new({}).prepended_scss
|
|
|
|
scss += ".body{background-image: absolute-image-url('/favicons/github.png');}"
|
|
|
|
css, _map = Stylesheet::Compiler.compile(scss, "test.scss")
|
|
|
|
|
|
|
|
expect(css).to include('url("http://test.localhost/images/favicons/github.png")')
|
|
|
|
expect(css).not_to include("absolute-image-url")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "supports absolute-image-url in subfolder" do
|
|
|
|
set_subfolder "/subfo"
|
|
|
|
scss = Stylesheet::Importer.new({}).prepended_scss
|
|
|
|
scss += ".body{background-image: absolute-image-url('/favicons/github.png');}"
|
|
|
|
css, _map = Stylesheet::Compiler.compile(scss, "test2.scss")
|
|
|
|
|
|
|
|
expect(css).to include('url("http://test.localhost/subfo/images/favicons/github.png")')
|
|
|
|
expect(css).not_to include("absolute-image-url")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "supports absolute-image-url with CDNs" do
|
|
|
|
set_cdn_url "https://awesome.com"
|
|
|
|
scss = Stylesheet::Importer.new({}).prepended_scss
|
|
|
|
scss += ".body{background-image: absolute-image-url('/favicons/github.png');}"
|
|
|
|
css, _map = Stylesheet::Compiler.compile(scss, "test2.scss")
|
|
|
|
|
|
|
|
expect(css).to include('url("https://awesome.com/images/favicons/github.png")')
|
|
|
|
expect(css).not_to include("absolute-image-url")
|
|
|
|
end
|
|
|
|
|
2021-05-03 14:40:02 -04:00
|
|
|
it "supports absolute-image-url in plugins" do
|
|
|
|
set_cdn_url "https://awesome.com"
|
|
|
|
scss = Stylesheet::Importer.new({}).prepended_scss
|
|
|
|
scss +=
|
|
|
|
".body{background-image: absolute-image-url('/plugins/discourse-special/images/somefile.png');}"
|
|
|
|
css, _map = Stylesheet::Compiler.compile(scss, "discourse-special.scss")
|
|
|
|
|
|
|
|
expect(css).to include(
|
|
|
|
'url("https://awesome.com/plugins/discourse-special/images/somefile.png")',
|
|
|
|
)
|
|
|
|
expect(css).not_to include("absolute-image-url")
|
|
|
|
end
|
|
|
|
|
2020-08-03 22:57:10 -04:00
|
|
|
context "with a color scheme" do
|
|
|
|
it "returns the default color definitions when no color scheme is specified" do
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset("color_definitions")
|
|
|
|
expect(css).to include("--header_background:")
|
|
|
|
expect(css).to include("--primary:")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns color definitions for a custom color scheme" do
|
|
|
|
cs =
|
|
|
|
Fabricate(
|
|
|
|
:color_scheme,
|
|
|
|
name: "Stylish",
|
|
|
|
color_scheme_colors: [
|
|
|
|
Fabricate(:color_scheme_color, name: "header_primary", hex: "88af8e"),
|
|
|
|
Fabricate(:color_scheme_color, name: "header_background", hex: "f8745c"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset("color_definitions", color_scheme_id: cs.id)
|
|
|
|
|
|
|
|
expect(css).to include("--header_background: #f8745c")
|
|
|
|
expect(css).to include("--header_primary: #88af8e")
|
2023-02-07 10:24:57 -05:00
|
|
|
expect(css).to include("--header_background-rgb: 248, 116, 92")
|
2020-08-03 22:57:10 -04:00
|
|
|
end
|
2020-08-06 09:46:17 -04:00
|
|
|
|
|
|
|
context "with a plugin" do
|
|
|
|
before do
|
2023-06-04 20:06:00 -04:00
|
|
|
plugin = plugin_from_fixtures("color_definition")
|
2020-08-06 09:46:17 -04:00
|
|
|
Discourse.plugins << plugin
|
|
|
|
plugin.activate!
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
Discourse.plugins.pop
|
|
|
|
DiscoursePluginRegistry.reset!
|
|
|
|
end
|
|
|
|
|
|
|
|
it "includes color definitions from plugins" do
|
|
|
|
css, _map = Stylesheet::Compiler.compile_asset("color_definitions")
|
|
|
|
|
|
|
|
expect(css).to include("--plugin-color")
|
|
|
|
end
|
|
|
|
end
|
2020-08-03 22:57:10 -04:00
|
|
|
end
|
2020-12-30 15:29:10 -05:00
|
|
|
|
|
|
|
describe "indexes" do
|
|
|
|
it "include all SCSS files in their respective folders" do
|
|
|
|
refs = []
|
|
|
|
|
|
|
|
Dir
|
|
|
|
.glob(Rails.root.join("app/assets/stylesheets/**/*/"))
|
|
|
|
.each do |dir|
|
|
|
|
Dir
|
|
|
|
.glob("#{dir}_index.scss")
|
|
|
|
.each do |indexfile|
|
|
|
|
contents = File.read indexfile
|
2023-01-09 06:18:21 -05:00
|
|
|
|
2020-12-30 15:29:10 -05:00
|
|
|
files = Dir["#{dir}*.scss"]
|
|
|
|
files -= Dir["#{dir}_index.scss"]
|
|
|
|
files.each do |path|
|
|
|
|
filename = File.basename(path, ".scss")
|
|
|
|
if !contents.match(/@import "#{filename}";/)
|
|
|
|
refs << "#{filename} import missing in #{indexfile}"
|
2023-01-09 06:18:21 -05:00
|
|
|
end
|
|
|
|
end
|
2020-12-30 15:29:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(refs).to eq([])
|
|
|
|
end
|
|
|
|
end
|
2023-02-01 06:21:15 -05:00
|
|
|
|
|
|
|
describe ".compile" do
|
|
|
|
it "produces RTL CSS when rtl option is given" do
|
|
|
|
css, _ = Stylesheet::Compiler.compile("a{right:1px}", "test.scss", rtl: true)
|
|
|
|
expect(css).to eq("a{left:1px}")
|
|
|
|
end
|
|
|
|
end
|
2017-04-12 10:52:52 -04:00
|
|
|
end
|