2019-04-30 08:27:42 +08:00
# frozen_string_literal: true
2022-07-28 10:27:38 +08:00
RSpec . describe ThemeJavascriptCompiler do
2022-09-01 18:50:46 +08:00
let ( :compiler ) { ThemeJavascriptCompiler . new ( 1 , " marks " ) }
2019-01-17 19:46:11 +08:00
2020-03-07 00:35:52 +08:00
describe " # append_raw_template " do
2020-05-06 00:15:03 +08:00
it " uses the correct template paths " do
2020-03-07 00:35:52 +08:00
template = " <h1>hello</h1> "
name = " /path/to/templates1 "
compiler . append_raw_template ( " #{ name } .raw " , template )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " addRawTemplate( \" #{ name } \" " )
2020-03-07 00:35:52 +08:00
name = " /path/to/templates2 "
compiler . append_raw_template ( " #{ name } .hbr " , template )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " addRawTemplate( \" #{ name } \" " )
2020-03-07 00:35:52 +08:00
name = " /path/to/templates3 "
compiler . append_raw_template ( " #{ name } .hbs " , template )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " addRawTemplate( \" #{ name } .hbs \" " )
2020-03-07 00:35:52 +08:00
end
end
2021-04-12 20:02:58 +08:00
describe " # append_ember_template " do
2022-09-01 18:50:46 +08:00
it " maintains module names so that discourse-boot.js can correct them " do
2021-04-12 20:02:58 +08:00
compiler . append_ember_template ( " /connectors/blah-1 " , " {{var}} " )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include (
2023-09-05 17:16:12 +08:00
" define( \" discourse/theme-1/connectors/blah-1 \" , [ \" exports \" , " ,
2022-10-19 01:20:10 +08:00
)
2021-04-12 20:02:58 +08:00
compiler . append_ember_template ( " connectors/blah-2 " , " {{var}} " )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include (
2023-09-05 17:16:12 +08:00
" define( \" discourse/theme-1/connectors/blah-2 \" , [ \" exports \" , " ,
2022-10-19 01:20:10 +08:00
)
2021-04-12 20:02:58 +08:00
compiler . append_ember_template ( " javascripts/connectors/blah-3 " , " {{var}} " )
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include (
2023-09-05 17:16:12 +08:00
" define( \" discourse/theme-1/javascripts/connectors/blah-3 \" , [ \" exports \" , " ,
2022-10-19 01:20:10 +08:00
)
2022-09-01 18:50:46 +08:00
end
end
describe " connector module name handling " do
it " separates colocated connectors to avoid module name clash " do
# Colocated under `/connectors`
compiler = ThemeJavascriptCompiler . new ( 1 , " marks " )
2022-10-19 17:49:01 +08:00
compiler . append_tree (
{
" connectors/outlet/blah-1.hbs " = > " {{var}} " ,
" connectors/outlet/blah-1.js " = > " console.log('test') " ,
} ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " discourse/theme-1/connectors/outlet/blah-1 " )
expect ( compiler . raw_content . to_s ) . to include (
" discourse/theme-1/templates/connectors/outlet/blah-1 " ,
)
2022-10-19 17:49:01 +08:00
expect ( JSON . parse ( compiler . source_map ) [ " sources " ] ) . to contain_exactly (
" connectors/outlet/blah-1.js " ,
" templates/connectors/outlet/blah-1.js " ,
)
2022-09-01 18:50:46 +08:00
# Colocated under `/templates/connectors`
compiler = ThemeJavascriptCompiler . new ( 1 , " marks " )
2022-10-19 17:49:01 +08:00
compiler . append_tree (
{
" templates/connectors/outlet/blah-1.hbs " = > " {{var}} " ,
" templates/connectors/outlet/blah-1.js " = > " console.log('test') " ,
} ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " discourse/theme-1/connectors/outlet/blah-1 " )
expect ( compiler . raw_content . to_s ) . to include (
" discourse/theme-1/templates/connectors/outlet/blah-1 " ,
)
2022-10-19 17:49:01 +08:00
expect ( JSON . parse ( compiler . source_map ) [ " sources " ] ) . to contain_exactly (
" connectors/outlet/blah-1.js " ,
" templates/connectors/outlet/blah-1.js " ,
)
2022-09-01 18:50:46 +08:00
# Not colocated
compiler = ThemeJavascriptCompiler . new ( 1 , " marks " )
2022-10-19 17:49:01 +08:00
compiler . append_tree (
{
" templates/connectors/outlet/blah-1.hbs " = > " {{var}} " ,
" connectors/outlet/blah-1.js " = > " console.log('test') " ,
} ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content . to_s ) . to include ( " discourse/theme-1/connectors/outlet/blah-1 " )
expect ( compiler . raw_content . to_s ) . to include (
" discourse/theme-1/templates/connectors/outlet/blah-1 " ,
)
2022-10-19 17:49:01 +08:00
expect ( JSON . parse ( compiler . source_map ) [ " sources " ] ) . to contain_exactly (
" connectors/outlet/blah-1.js " ,
" templates/connectors/outlet/blah-1.js " ,
)
2022-09-01 18:50:46 +08:00
end
end
describe " error handling " do
it " handles syntax errors in raw templates " do
expect do
compiler . append_raw_template ( " sometemplate.hbr " , " {{invalidtemplate " )
end . to raise_error ( ThemeJavascriptCompiler :: CompileError , / Parse error on line 1 / )
end
it " handles syntax errors in ember templates " do
expect do
compiler . append_ember_template ( " sometemplate " , " {{invalidtemplate " )
end . to raise_error ( ThemeJavascriptCompiler :: CompileError , / Parse error on line 1 / )
2021-04-12 20:02:58 +08:00
end
end
2022-10-17 22:04:04 +08:00
describe " # append_tree " do
it " can handle multiple modules " do
compiler . append_tree (
{
" discourse/components/mycomponent.js " = > << ~ JS ,
import Component from " @glimmer/component " ;
export default class MyComponent extends Component { }
JS
" discourse/templates/components/mycomponent.hbs " = > " {{my-component-template}} " ,
} ,
)
2023-08-19 01:15:23 +08:00
expect ( compiler . raw_content ) . to include (
'define("discourse/theme-1/discourse/components/mycomponent"' ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content ) . to include (
'define("discourse/theme-1/discourse/templates/components/mycomponent"' ,
)
2022-10-17 22:04:04 +08:00
end
2022-10-17 21:47:16 +08:00
it " handles colocated components " do
compiler . append_tree (
{
" discourse/components/mycomponent.js " = > << ~ JS ,
import Component from " @glimmer/component " ;
export default class MyComponent extends Component { }
JS
" discourse/components/mycomponent.hbs " = > " {{my-component-template}} " ,
} ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content ) . to include ( " __COLOCATED_TEMPLATE__ = " )
expect ( compiler . raw_content ) . to include ( " setComponentTemplate " )
2022-10-17 21:47:16 +08:00
end
2022-12-07 22:24:03 +08:00
it " handles colocated admin components " do
compiler . append_tree (
{
" admin/components/mycomponent.js " = > << ~ JS ,
import Component from " @glimmer/component " ;
export default class MyComponent extends Component { }
JS
" admin/components/mycomponent.hbs " = > " {{my-component-template}} " ,
} ,
)
expect ( compiler . raw_content ) . to include ( " __COLOCATED_TEMPLATE__ = " )
expect ( compiler . raw_content ) . to include ( " setComponentTemplate " )
end
2022-10-22 02:05:34 +08:00
it " applies theme AST transforms to colocated components " do
compiler = ThemeJavascriptCompiler . new ( 12_345_678_910 , " my theme name " )
compiler . append_tree (
{ " discourse/components/mycomponent.hbs " = > '{{theme-i18n "my_translation_key"}}' } ,
)
template_compiled_line = compiler . raw_content . lines . find { | l | l . include? ( '"block":' ) }
expect ( template_compiled_line ) . to include ( " 12345678910 " )
end
2022-10-17 21:47:16 +08:00
it " prints error when default export missing " do
compiler . append_tree (
{
" discourse/components/mycomponent.js " = > << ~ JS ,
import Component from " @glimmer/component " ;
class MyComponent extends Component { }
JS
" discourse/components/mycomponent.hbs " = > " {{my-component-template}} " ,
} ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content ) . to include ( " __COLOCATED_TEMPLATE__ = " )
expect ( compiler . raw_content ) . to include ( " throw new Error " )
2022-10-17 21:47:16 +08:00
end
it " handles template-only components " do
compiler . append_tree (
{ " discourse/components/mycomponent.hbs " = > " {{my-component-template}} " } ,
)
2022-10-19 01:20:10 +08:00
expect ( compiler . raw_content ) . to include ( " __COLOCATED_TEMPLATE__ = " )
expect ( compiler . raw_content ) . to include ( " setComponentTemplate " )
expect ( compiler . raw_content ) . to include ( " @ember/component/template-only " )
end
end
describe " terser compilation " do
it " applies terser and provides sourcemaps " do
sources = {
" multiply.js " = > " let multiply = (firstValue, secondValue) => firstValue * secondValue; " ,
" add.js " = > " let add = (firstValue, secondValue) => firstValue + secondValue; " ,
}
compiler . append_tree ( sources )
expect ( compiler . content ) . to include ( " multiply " )
expect ( compiler . content ) . to include ( " add " )
map = JSON . parse ( compiler . source_map )
expect ( map [ " sources " ] ) . to contain_exactly ( * sources . keys )
expect ( map [ " sourcesContent " ] . to_s ) . to include ( " let multiply " )
expect ( map [ " sourcesContent " ] . to_s ) . to include ( " let add " )
expect ( map [ " sourceRoot " ] ) . to eq ( " theme-1/ " )
end
it " handles invalid JS " do
compiler . append_raw_script ( " filename.js " , " if(someCondition " )
expect ( compiler . content ) . to include ( 'console.error("[THEME 1' )
expect ( compiler . content ) . to include ( " Unexpected token " )
2022-10-17 21:47:16 +08:00
end
2022-10-17 22:04:04 +08:00
end
2023-09-05 17:16:12 +08:00
describe " ember-this-fallback " do
it " applies its transforms " do
compiler . append_tree (
{
" discourse/components/my-component.js " = > << ~ JS ,
import Component from " @glimmer/component " ;
export default class MyComponent extends Component {
value = " foo " ;
}
JS
" discourse/components/my-component.hbs " = > " {{value}} " ,
} ,
)
expect ( compiler . raw_content ) . to include ( " ember-this-fallback " )
expect ( compiler . raw_content ) . to include (
" The `value` property path was used in the `discourse/components/my-component.hbs` template without using `this`. This fallback behavior has been deprecated, all properties must be looked up on `this` when used in the template: {{this.value}} " ,
)
end
end
2023-10-02 18:36:06 +08:00
describe " ember-template-imports " do
it " applies its transforms " do
compiler . append_tree ( { " discourse/components/my-component.gjs " = > << ~ JS } )
import Component from " @glimmer/component " ;
export default class MyComponent extends Component {
< template >
{ { this . value } }
< / template>
value = " foo " ;
}
JS
expect ( compiler . raw_content ) . to include (
" define( \" discourse/theme-1/discourse/components/my-component \" , [ \" exports \" , " ,
)
2024-06-10 22:51:48 +08:00
expect ( compiler . raw_content ) . to include ( 'value = "foo";' )
2023-10-02 18:36:06 +08:00
expect ( compiler . raw_content ) . to include ( " setComponentTemplate " )
expect ( compiler . raw_content ) . to include ( " createTemplateFactory " )
end
end
2024-06-10 22:51:48 +08:00
describe " safari <16 class field bugfix " do
it " is applied " do
compiler . append_tree ( { " discourse/components/my-component.js " = > << ~ JS } )
export default class MyComponent extends Component {
value = " foo " ;
complexValue = this . value + " bar " ;
}
JS
expect ( compiler . raw_content ) . to include ( 'value = "foo";' )
expect ( compiler . raw_content ) . to include ( 'complexValue = (() => this.value + "bar")();' )
end
end
2019-01-17 19:46:11 +08:00
end