Skip to content

Commit

Permalink
Merge pull request #22 from nontangent/refactor/clean-code
Browse files Browse the repository at this point in the history
Refactor/clean code
  • Loading branch information
nontangent authored Dec 2, 2022
2 parents d32958f + e7887cb commit ecb4ca0
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 179 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Ng Atomic(Beta)
Not recommended because the interface is unstable. Don't believe what it says!

# Ng Atomic(Alpha)
This is an atomic design system framework based on Angular for all web platforms such as React, Vue or of cource Angular.

<strong><pre>ng add @ng-atomic/schematics</pre></strong>
Expand Down Expand Up @@ -61,7 +63,7 @@ $ ng g @ng-atomic/schematics:components
## @ng-atomic/components
Base components for Atomic Design System

Look at [the storybook]().
Look at [the storybook](https://nontangent.github.io/ng-atomic/storybook/).


## @ng-atomic/elements
Expand Down
45 changes: 45 additions & 0 deletions libs/schematics/src/gpt3/distance.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { calculateDistance, convertByWords, parseFilePath, standarization } from './distance';

describe('standarization', () => {
it('', () => {
expect(standarization(
'/libs/example/src/lib/domain/models/first-model.ts',
'/libs/example/src/lib/domain/models/second-model.ts',
)).toEqual([
'/0/1/2/3/4/5/6.7',
'/0/1/2/3/4/5/8.7',
])
});
});

describe('calculateDistance()', () => {
it('', () => {
expect(calculateDistance(
'/libs/example/src/lib/domain/models/first-model.ts',
'/libs/example/src/lib/domain/models/second-model.ts',
)).toEqual(1)
});

it('', () => {
expect(calculateDistance(
'/libs/example/src/lib/domain/models/first-model.component.ts',
'/libs/example/src/lib/domain/models/second-model.module.ts',
)).toEqual(2)
});
});

describe('parseFilePath', () => {
it('should parse file path', () => {
expect(parseFilePath('/projects/app/src/app/_shared/components/example/example.component.ts')).toEqual([
'/', 'projects', '/', 'app', '/', 'src', '/', 'app', '/', '_shared', '/',
'components', '/', 'example', '/', 'example', '.', 'component', '.', 'ts'
]);
});
});

describe('convertByWords', () => {
xit('should convert from a string to a number', () => {
expect(convertByWords('this/is/test/path', ['this', 'is', 'test', 'path'])).toBe('0/1/2/3');
});
});

68 changes: 68 additions & 0 deletions libs/schematics/src/gpt3/distance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export function standarization(str1: string, str2: string): [string, string] {
const wordSet = new Set([str1, str2].map(path => parseFilePath(path)).flat());
wordSet.delete('.');
wordSet.delete('/');
return [convertByWords(str1, [...wordSet]), convertByWords(str2, [...wordSet])];
}

export function calculateDistance(str1: string, str2: string): number {
const [s1, s2] = standarization(str1, str2);
return levenshteinDistance(s1, s2) + depthDistance(str1, str2);
}

const LANG_MAP = `0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=[]{};:'",.<>/?|\\~\` `.split('');

export function convertByWords(str: string, words: string[]): string {
return parseFilePath(str).map(c => ~words.indexOf(c) ? LANG_MAP[words.indexOf(c)] : c).join('');
}

export function parseFilePath(filePath: string, characters = ['.', '/']): string[] {
const result = [];
let word = '';
for (let i = 0; i < filePath.length; i++) {
const char = filePath[i];
if (characters.includes(char)) {
if (word.length) result.push(word);
result.push(char);
word = '';
} else {
word += char;
}
}
result.push(word);
return result;
}

function depthDistance(str1: string, str2: string): number {
const depth1 = str1.split('/').length;
const depth2 = str2.split('/').length;
return Math.abs(depth1 - depth2);
}


function levenshteinDistance(str1: string, str2: string): number {
const cost = (a: string, b: string): number => {
return a === b ? 0 : 1;
}

const d = [];
for (let i = 0; i <= str1.length; i++) {
d[i] = [];
d[i][0] = i;
}
for (let j = 0; j <= str2.length; j++) {
d[0][j] = j;
}

for (let i = 1; i <= str1.length; i++) {
for (let j = 1; j <= str2.length; j++) {
d[i][j] = Math.min(
d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + cost(str1[i - 1], str2[j - 1])
);
}
}

return d[str1.length][str2.length];
}
28 changes: 11 additions & 17 deletions libs/schematics/src/gpt3/helpers.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getEstimateSimilarFilePaths, convertByWords, parseFilePath } from './helpers';
import { getEstimateSimilarFilePaths } from './helpers';

describe('getEstimateSimilarFilePaths', () => {
const FILES = [
Expand All @@ -18,8 +18,18 @@ describe('getEstimateSimilarFilePaths', () => {
'/projects/app/src/app/_shared/components/test/test.component.ts',
'/projects/app/src/app/_shared/components/test/test.stories.ts',
'/projects/app/src/app/_shared/components/test/index.ts',
'/libs/nm-common/src/lib/domain/models/invoice.ts',
'/libs/nm-common/src/lib/domain/models/contract.ts',
];

it('', () => {
const result = getEstimateSimilarFilePaths('/libs/nm-common/src/lib/domain/models/customer.ts', FILES);
expect(result).toEqual([
'/libs/nm-common/src/lib/domain/models/invoice.ts',
'/libs/nm-common/src/lib/domain/models/contract.ts',
]);
});

it('', () => {
const file = '/projects/app/src/app/_shared/components/expected/expected.component.ts';
const files = getEstimateSimilarFilePaths(file, FILES);
Expand All @@ -38,19 +48,3 @@ describe('getEstimateSimilarFilePaths', () => {
]);
});
});

describe('parseFilePath', () => {
it('should parse file path', () => {
expect(parseFilePath('/projects/app/src/app/_shared/components/example/example.component.ts')).toEqual([
'/', 'projects', '/', 'app', '/', 'src', '/', 'app', '/', '_shared', '/',
'components', '/', 'example', '/', 'example', '.', 'component', '.', 'ts'
]);
});
});

describe('convertByWords', () => {
xit('should convert from a string to a number', () => {
expect(convertByWords('this/is/test/path', ['this', 'is', 'test', 'path'])).toBe('0/1/2/3');
});
});

65 changes: 2 additions & 63 deletions libs/schematics/src/gpt3/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,7 @@

export function parseFilePath(filePath: string, characters = ['.', '/']): string[] {
const result = [];
let word = '';
for (let i = 0; i < filePath.length; i++) {
const char = filePath[i];
if (characters.includes(char)) {
if (word.length) result.push(word);
result.push(char);
word = '';
} else {
word += char;
}
}
result.push(word);
return result;
}

export const convertByWords = (str: string, words: string[]): string => {
return parseFilePath(str).map(c => ~words.indexOf(c) ? words.indexOf(c) : c).join('');
}
import { calculateDistance } from "./distance";

export function getEstimateSimilarFilePaths(path: string, files: string[]): string[] {
const wordSet = new Set([path, ...files].map(path => parseFilePath(path)).flat());
wordSet.delete('.');
wordSet.delete('/');
const words = Array.from(wordSet);
const results = files.map(file => {
const distance = levenshteinDistance(convertByWords(path, words), convertByWords(file, words)) + depthDistance(path, file);
return [distance, file] as [number, string];
});
const results = files.map(file => [calculateDistance(path, file), file] as [number, string]);
const min = Math.min(...results.map(([distance]) => distance));
return results.filter(([distance]) => distance === min).map(([_, file]) => file);
}

function depthDistance(str1: string, str2: string): number {
const depth1 = str1.split('/').length;
const depth2 = str2.split('/').length;
return Math.abs(depth1 - depth2);
}


function levenshteinDistance(str1: string, str2: string): number {
const cost = (a: string, b: string): number => {
return a === b ? 0 : 1;
}

const d = [];
for (let i = 0; i <= str1.length; i++) {
d[i] = [];
d[i][0] = i;
}
for (let j = 0; j <= str2.length; j++) {
d[0][j] = j;
}

for (let i = 1; i <= str1.length; i++) {
for (let j = 1; j <= str2.length; j++) {
d[i][j] = Math.min(
d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + cost(str1[i - 1], str2[j - 1])
);
}
}

return d[str1.length][str2.length];
}
23 changes: 11 additions & 12 deletions libs/schematics/src/gpt3/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import path from 'path';
import { createWorkspace } from '../_testing';
import { parseJsonCodeBlock, parseCodeBlocks } from './index';

jest.setTimeout(300 * 1000);

Expand All @@ -11,7 +10,7 @@ describe('Gpt Schematics', () => {
const runner = new SchematicTestRunner('@ng-atomic/schematics', COLLECTION_PATH);
let tree: UnitTestTree;

describe('Angular Workspace', () => {
xdescribe('Angular Workspace', () => {
beforeEach(async () => {
tree = await createWorkspace(runner, tree);
tree = await runner.runSchematicAsync('atomic-component', {
Expand Down Expand Up @@ -80,11 +79,11 @@ const TEST = `
// });
// });

describe('parseJsonCodeBlock', () => {
it('should parse json code block', () => {
expect(parseJsonCodeBlock(TEST)).toBeTruthy();
});
});
// describe('parseJsonCodeBlock', () => {
// it('should parse json code block', () => {
// expect(parseJsonCodeBlock(TEST)).toBeTruthy();
// });
// });


const CODE_BLOCKS = `
Expand Down Expand Up @@ -149,8 +148,8 @@ export class ExpectedComponent implements OnInit {
\`\`\`
`;

describe('parseCodeBlocks', () => {
it('should parse code blocks', () => {
expect(parseCodeBlocks(CODE_BLOCKS)).toBeTruthy();
});
});
// describe('parseCodeBlocks', () => {
// it('should parse code blocks', () => {
// expect(parseCodeBlocks(CODE_BLOCKS)).toBeTruthy();
// });
// });
Loading

0 comments on commit ecb4ca0

Please sign in to comment.