Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file usages for route templates (upper routes support) #160

Merged
merged 14 commits into from
Nov 1, 2020
7 changes: 4 additions & 3 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import ScriptCompletionProvider from './completion-provider/script-completion-pr
import { getRegistryForRoot, addToRegistry, REGISTRY_KIND, normalizeMatchNaming } from './utils/registry-api';
import { Usage, findRelatedFiles } from './utils/usages-api';
import { URI } from 'vscode-uri';
import { MatchResultType } from './utils/path-matcher';

export default class Server {
initializers: any[] = [];
Expand All @@ -75,8 +76,8 @@ export default class Server {
return false;
}
}
getUsages(normalizedToken: string): Usage[] {
return findRelatedFiles(normalizedToken);
getUsages(normalizedToken: string, resultType: MatchResultType): Usage[] {
return findRelatedFiles(normalizedToken, resultType);
}
getRegistry(rawRoot: string) {
return getRegistryForRoot(path.resolve(rawRoot));
Expand Down Expand Up @@ -176,7 +177,7 @@ export default class Server {
name: item.name,
path: filePath,
type: item.type,
usages: this.getUsages(item.name).map((usage) => {
usages: this.getUsages(item.name, item.type).map((usage) => {
if (usage.type === 'routePath') {
return {
...usage,
Expand Down
53 changes: 52 additions & 1 deletion src/utils/usages-api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { extractTokensFromTemplate } from './template-tokens-collector';
import * as fs from 'fs';
import { MatchResultType } from './path-matcher';

export interface TemplateTokenMeta {
source: string;
Expand Down Expand Up @@ -27,7 +28,21 @@ export interface Usage {
usages: Usage[];
}

export function findRelatedFiles(token: string): Usage[] {
export function closestParentRoutePath(name: string): string | null {
const lastIndexOfDot = name.lastIndexOf('/');

if (name.endsWith('-loading') || name.endsWith('-error')) {
return name.slice(0, name.lastIndexOf('-'));
}

if (lastIndexOfDot === undefined || lastIndexOfDot < 0) {
return null;
}

return name.slice(0, lastIndexOfDot);
}

export function findRelatedFiles(token: string, tokenType: MatchResultType = 'component'): Usage[] {
const results: Usage[] = [];

Object.keys(TEMPLATE_TOKENS).forEach((kindName) => {
Expand All @@ -45,6 +60,42 @@ export function findRelatedFiles(token: string): Usage[] {
});
});

if (tokenType === 'template') {
const routeTemplates = TEMPLATE_TOKENS.routePath;
let parent: string | null = token;

do {
parent = closestParentRoutePath(parent);

if (parent !== null) {
const normalizedParentName = parent.split('/').join('.');

if (routeTemplates[normalizedParentName]) {
results.push({
name: normalizedParentName,
path: routeTemplates[normalizedParentName].source,
type: 'routePath',
usages: [],
});
break;
}
} else {
break;
}
} while (parent);

if (results.length === 0 && token !== 'application') {
if (routeTemplates['application']) {
results.push({
name: 'application',
path: routeTemplates['application'].source,
type: 'routePath',
usages: [],
});
}
}
}

return results;
}

Expand Down
44 changes: 43 additions & 1 deletion test/utils/usages-api-test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { updateTemplateTokens, findRelatedFiles } from '../../src/utils/usages-api';
import { updateTemplateTokens, closestParentRoutePath, findRelatedFiles } from '../../src/utils/usages-api';
import { createTempDir } from 'broccoli-test-helper';
import * as path from 'path';
let dir = null;
Expand All @@ -19,6 +19,12 @@ function createFile(name: string, content: string): string {
}

describe('Usages API', () => {
it('should return closest upper path', () => {
expect(closestParentRoutePath('foo/bar')).toBe('foo');
expect(closestParentRoutePath('foo-loading')).toBe('foo');
expect(closestParentRoutePath('foo-error')).toBe('foo');
expect(closestParentRoutePath('foo/bar/baz')).toBe('foo/bar');
});
it('should extract component template tokens by giving path', () => {
expect(findRelatedFiles('foo-bar').length).toBe(0);

Expand All @@ -43,4 +49,40 @@ describe('Usages API', () => {

expect(findRelatedFiles('foo-bar').length).toBe(0);
});
it('should return usages for closest routes (upper)', () => {
expect(findRelatedFiles('foo/bar/baz', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'foo.bar', createFile('bar.hbs', ''));
expect(findRelatedFiles('foo/bar/baz', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'foo.bar', null);
});
it('should return usages for closest available routes (upper)', () => {
expect(findRelatedFiles('foo/bar/baz', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'foo', createFile('bar.hbs', ''));
expect(findRelatedFiles('foo/bar/baz', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'foo', null);
});
it('should return usages for closest available routes, in index case', () => {
expect(findRelatedFiles('index', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'application', createFile('bar.hbs', ''));
expect(findRelatedFiles('index', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'application', null);
});
it('should return usages for closest available routes, in loading case', () => {
expect(findRelatedFiles('index-loading', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'index', createFile('bar.hbs', ''));
expect(findRelatedFiles('index-loading', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'index', null);
});
it('should return usages for closest available routes, in error case', () => {
expect(findRelatedFiles('index-error', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'index', createFile('bar.hbs', ''));
expect(findRelatedFiles('index-error', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'index', null);
});
it('should return root template for case if no parents by path', () => {
expect(findRelatedFiles('groups-loading', 'template').length).toBe(0);
updateTemplateTokens('routePath', 'application', createFile('bar.hbs', ''));
expect(findRelatedFiles('groups-loading', 'template').length).toBe(1);
updateTemplateTokens('routePath', 'application', null);
});
});