diff --git a/package.json b/package.json index 7106e60d69..4c9b5614be 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "types": "types/runtime", "scripts": { "test": "mocha --opts mocha.opts", - "test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts", + "test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts", "quicktest": "mocha --opts mocha.opts", "precoverage": "c8 mocha --opts mocha.coverage.opts", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 896f235c61..973847a1b9 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -6,6 +6,7 @@ import render_ssr from './render-ssr/index'; import { CompileOptions, Warning } from '../interfaces'; import Component from './Component'; import fuzzymatch from '../utils/fuzzymatch'; +import { get_name_from_filename } from './utils/get_name_from_filename'; const valid_options = [ 'format', @@ -55,33 +56,6 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { } } -function get_name(filename: string) { - if (!filename) return null; - // eslint-disable-next-line no-useless-escape - const parts = filename.split(/[\/\\]/); - - if (parts.length > 1) { - const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); - if (index_match) { - parts.pop(); - parts[parts.length - 1] += index_match[1]; - } - } - - const base = parts.pop() - .replace(/\.[^.]+$/, "") - .replace(/[^a-zA-Z_$0-9]+/g, '_') - .replace(/^_/, '') - .replace(/_$/, '') - .replace(/^(\d)/, '_$1'); - - if (!base) { - throw new Error(`Could not derive component name from file ${filename}`); - } - - return base[0].toUpperCase() + base.slice(1); -} - export default function compile(source: string, options: CompileOptions = {}) { options = assign({ generate: 'dom', dev: false }, options); @@ -98,7 +72,7 @@ export default function compile(source: string, options: CompileOptions = {}) { const component = new Component( ast, source, - options.name || get_name(options.filename) || 'Component', + options.name || get_name_from_filename(options.filename) || 'Component', options, stats, warnings diff --git a/src/compiler/compile/utils/__test__.ts b/src/compiler/compile/utils/__test__.ts index 7a8b5a6fd7..b5bc5d8ea8 100644 --- a/src/compiler/compile/utils/__test__.ts +++ b/src/compiler/compile/utils/__test__.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import deindent from './deindent'; import CodeBuilder from './CodeBuilder'; +import get_name_from_filename from './get_name_from_filename'; describe('deindent', () => { it('deindents a simple string', () => { @@ -164,3 +165,17 @@ describe('CodeBuilder', () => { ); }); }); + +describe('get_name_from_filename', () => { + it('uses the basename', () => { + assert.equal(get_name_from_filename('path/to/Widget.svelte'), 'Widget'); + }); + + it('uses the directory name, if basename is index', () => { + assert.equal(get_name_from_filename('path/to/Widget/index.svelte'), 'Widget'); + }); + + it('handles unusual filenames', () => { + assert.equal(get_name_from_filename('path/to/[...parts].svelte'), 'Parts'); + }); +}); diff --git a/src/compiler/compile/utils/get_name_from_filename.ts b/src/compiler/compile/utils/get_name_from_filename.ts new file mode 100644 index 0000000000..19c781825c --- /dev/null +++ b/src/compiler/compile/utils/get_name_from_filename.ts @@ -0,0 +1,26 @@ +export default function get_name_from_filename(filename: string) { + if (!filename) return null; + // eslint-disable-next-line no-useless-escape + const parts = filename.split(/[\/\\]/); + + if (parts.length > 1) { + const index_match = parts[parts.length - 1].match(/^index(\.\w+)/); + if (index_match) { + parts.pop(); + parts[parts.length - 1] += index_match[1]; + } + } + + const base = parts.pop() + .replace(/\.[^.]+$/, "") + .replace(/[^a-zA-Z_$0-9]+/g, '_') + .replace(/^_/, '') + .replace(/_$/, '') + .replace(/^(\d)/, '_$1'); + + if (!base) { + throw new Error(`Could not derive component name from file ${filename}`); + } + + return base[0].toUpperCase() + base.slice(1); +} \ No newline at end of file