Skip to content

Commit

Permalink
refactor: fix types, remove applyMethod function and update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aykutkardas committed Feb 23, 2024
1 parent aa6fb5c commit f85e4b2
Show file tree
Hide file tree
Showing 18 changed files with 115 additions and 109 deletions.
23 changes: 0 additions & 23 deletions src/config/applyMethods.ts

This file was deleted.

7 changes: 3 additions & 4 deletions src/config/getConfig.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import parseSelector from './parseSelector';
import { ElementPassArg } from '../parser/types';
import { Config, RawConfig } from './types';
import { applyMethods } from './applyMethods';
import { type ElementPassArg } from '../parser/types';
import { type Config, type RawConfig } from './types';

function getConfig(
{ $, el }: ElementPassArg,
Expand Down Expand Up @@ -51,7 +50,7 @@ function getConfig<Initial = unknown>(
};
}

return applyMethods(config);
return config;
}

export default getConfig;
47 changes: 38 additions & 9 deletions src/config/parseSelector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Selector, RawConfig } from './types';
import { type Selector, type RawConfig, type Method } from './types';

function parseSelector<Initial = unknown>(
selector: Selector
Expand All @@ -14,7 +14,43 @@ function parseSelector<Initial = unknown>(
if (selector.includes('|')) {
[$selector, ...methods] = selector.split('|').map((key) => key.trim());

methods = methods.map((p: string) => p.trim());
if (methods.length > 0) {
const validMethods = [
'boolean',
'float',
'number',
'length',
'lowercase',
'uppercase',
'email',
'url'
];

const acceptedMethods = methods.filter((method: string) =>
validMethods.includes(method)
) as Method[];

const type = methods.includes('array') ? 'array' : config.type;
const html = methods.includes('html') ? true : config.html;
const exist = methods.includes('exist') ? true : config.exist;

let trim = config.trim;

if (methods.includes('trim')) {
trim = true;
} else if (methods.includes('non-trim')) {
trim = false;
}

if (type) config.type = type;
if (html) config.html = html;
if (exist) config.exist = exist;
if (typeof trim === 'boolean') config.trim = trim;

if (acceptedMethods.length > 0) {
config.methods = acceptedMethods;
}
}
}

if ($selector === undefined) {
Expand All @@ -34,13 +70,6 @@ function parseSelector<Initial = unknown>(

if (attr) config.attr = attr;

if (methods?.length) {
if (methods.includes('array')) {
config.type = 'array';
}
config.methods = methods.filter((i) => i !== 'array');
}

return config;
}

Expand Down
16 changes: 13 additions & 3 deletions src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,30 @@ export type ElementFilterFunction = (
$: CheerioAPI
) => boolean;

export type ConfigTypeValues = 'number' | 'float' | 'boolean' | 'array';
export type Method =
| 'boolean'
| 'number'
| 'float'
| 'length'
| 'lowercase'
| 'uppercase'
| 'email'
| 'url';

export type Types = 'number' | 'float' | 'boolean' | 'array';

export interface RawConfig<Initial = unknown> {
selector?: Selector;
html?: boolean;
attr?: string | string[];
type?: ConfigTypeValues;
type?: Types;
trim?: boolean;
exist?: boolean;
rootScope?: boolean;
elementFilter?: ElementFilterFunction;
initial?: Initial;
fill?: any;
methods?: string[];
methods?: Method[];
regex?: RegexConfig;
transform?: TransformFunction<Initial>;
arrayTransform?: TransformFunction<any[]>;
Expand Down
4 changes: 1 addition & 3 deletions src/parser/getValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ function getValue<Initial = unknown>(
const { schema } = rest;
const elemExists = element.length > 0;

if (exist || config.methods?.includes('exist')) {
return elemExists;
}
if (exist) return elemExists;

if (condition && !condition($(el))) {
return rest.initial ?? null;
Expand Down
2 changes: 1 addition & 1 deletion src/parser/methods/boolean.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const boolean = (val: any): boolean => Boolean(val);
const boolean = (val: any) => Boolean(val);

export default boolean;
2 changes: 1 addition & 1 deletion src/parser/methods/email.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import execRegex from '../regex/execRegex';

const email = (val: any): string => execRegex(val, 'email');
const email = (val: any) => execRegex(val, 'email');

export default email;
2 changes: 1 addition & 1 deletion src/parser/methods/float.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const float = (val: string): number => parseFloat(val);
const float = (val: string) => parseFloat(val);

export default float;
2 changes: 1 addition & 1 deletion src/parser/methods/length.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const length = (val: any): number => val?.length || 0;
const length = (val: any) => val?.length || 0;

export default length;
2 changes: 1 addition & 1 deletion src/parser/methods/lowercase.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const lowercase = (val: string): string => val.toLowerCase();
const lowercase = (val: string) => val.toLowerCase();

export default lowercase;
2 changes: 1 addition & 1 deletion src/parser/methods/number.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const number = (val: string): number => parseInt(val);
const number = (val: string) => parseInt(val);

export default number;
2 changes: 1 addition & 1 deletion src/parser/methods/uppercase.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const uppercase = (val: string): string => val.toUpperCase();
const uppercase = (val: string) => val.toUpperCase();

export default uppercase;
2 changes: 1 addition & 1 deletion src/parser/methods/url.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import execRegex from '../regex/execRegex';

const url = (val: any): string => execRegex(val, 'url');
const url = (val: any) => execRegex(val, 'url');

export default url;
5 changes: 2 additions & 3 deletions src/parser/transformValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { Cheerio, Element } from 'cheerio';
import { RawConfig } from '../config/types';
import Methods from './methods';
import execRegex from './regex/execRegex';
import { Value } from './value';

function transformValue<Initial = unknown>(
value: Value<Initial>,
value: any,
config: RawConfig<Initial>,
element: Cheerio<Element>
) {
Expand All @@ -19,7 +18,7 @@ function transformValue<Initial = unknown>(
if (value) value = value.trim();
}

if (type) {
if (type && type !== 'array') {
methods.push(type);
}

Expand Down
63 changes: 29 additions & 34 deletions tests/getConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import { describe, it, expect } from 'vitest';

import getConfig from '../src/config/getConfig';
import parseSelector from '../src/config/parseSelector';
import { RawConfig } from '../src/config/types';

describe('getConfig Tests', () => {
it('Case 1: string config: @ attr', () => {
const config = { selector: '@ href' };
it('should return empty selector and "href" attribute when given a string config with "@ attr"', () => {
const config: RawConfig = { selector: '@ href' };
const value = getConfig({}, config);
const expected = { selector: '', attr: 'href' };

expect(value).to.deep.equal(expected);
});

it('Case 2: string config: selector', () => {
const config = { selector: 'a.link' };
it('should return the same selector when given a string config without "@ attr"', () => {
const config: RawConfig = { selector: 'a.link' };
const value = getConfig({}, config);
expect({ selector: 'a.link' }).to.deep.equal(value);
});

it('Case 3: string config: selector @ attr', () => {
const config = { selector: 'a.link @ href' };
it('should return the selector and "href" attribute when given a string config with "selector @ attr"', () => {
const config: RawConfig = { selector: 'a.link @ href' };
const value = getConfig({}, config);
expect({ selector: 'a.link', attr: 'href' }).to.deep.equal(value);
});

it('Case 4: array config: [selector, selector]', () => {
const config = { selector: 'a.link, b.link' };
it('should return the same selector when given an array config with multiple selectors', () => {
const config: RawConfig = { selector: 'a.link, b.link' };
const value = getConfig({}, config);
expect({ selector: 'a.link, b.link' }).to.deep.equal(value);
});

it('Case 5: object config: { selector, attr }', () => {
const config = { selector: 'a.link', attr: 'href' };
it('should return the selector and attribute when given an object config with "selector" and "attr"', () => {
const config: RawConfig = { selector: 'a.link', attr: 'href' };
const value = getConfig({}, config);
expect({ selector: 'a.link', attr: 'href' }).to.deep.equal(value);
});

it('Case 6: object config: { selector @ attr }', () => {
const config = { selector: 'a.link @ href' };
it('should return the selector and attribute when given an object config with "selector @ attr"', () => {
const config: RawConfig = { selector: 'a.link @ href' };
const value = getConfig({}, config);
expect({ selector: 'a.link', attr: 'href' }).to.deep.equal(value);
});

it('Case 7: object config: { selector @ attr | method }', () => {
const config = { selector: 'a.link @ href | url' };
it('should return the selector, attribute, and methods when given an object config with "selector @ attr | method"', () => {
const config: RawConfig = { selector: 'a.link @ href | url' };
const value = getConfig({}, config);
expect({
selector: 'a.link',
Expand All @@ -52,58 +52,53 @@ describe('getConfig Tests', () => {
}).to.deep.equal(value);
});

it('Case 8: object config: { selector @ attr | array* }', () => {
const config = { selector: 'a.link @ href | array' };
it('should return the selector, attribute, and type when given an object config with "selector @ attr | array"', () => {
const config: RawConfig = { selector: 'a.link @ href | array' };
const value = getConfig({}, config);
expect({
selector: 'a.link',
attr: 'href',
type: 'array',
methods: []
type: 'array'
}).to.deep.equal(value);
});

it('Case 9: object config: { selector @ attr | html* }', () => {
const config = { selector: 'a.link @ href | html' };
it('should return the selector, attribute, and html flag when given an object config with "selector @ attr | html"', () => {
const config: RawConfig = { selector: 'a.link @ href | html' };
const value = getConfig({}, config);
expect({
selector: 'a.link',
attr: 'href',
html: true,
methods: ['html']
html: true
}).to.deep.equal(value);
});

it('Case 10: object config: () => ({ selector @ attr | html* })', () => {
const config = {
it('should return the selector, attribute, and html flag when given an object config as a function', () => {
const config: RawConfig = {
selector: 'a.link @ href | html'
};
const value = getConfig({}, config);
const expected = {
selector: 'a.link',
attr: 'href',
html: true,
methods: ['html']
html: true
};

expect(value).to.deep.equal(expected);
});

it('Case 11: object config: () => ({ selector | exist })', () => {
const config = { selector: 'a.link | exist' };
it('should return the selector and exist flag when given an object config as a function', () => {
const config: RawConfig = { selector: 'a.link | exist' };
const value = getConfig({}, config);
expect({
selector: 'a.link',
exist: true,
methods: ['exist']
exist: true
}).to.deep.equal(value);
});

it('MultipleStringSelectors', () => {
it('should return the parsed selectors when given an array of string selectors', () => {
const selectors = ['a.link', 'b.link'];
const result = getConfig({}, selectors);
const expected = selectors.map((s) => parseSelector(s));

const expected = [{ selector: 'a.link' }, { selector: 'b.link' }];
expect(result).to.deep.equal(expected);
});
});
2 changes: 1 addition & 1 deletion tests/getValue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ describe('getValue Tests', () => {
it('Case 17: { selector, non-exist }', () => {
const el = $('.parent');
const selector = '.non-exist-child';
const value = getValue({ $, el }, { selector, methods: ['exist'] });
const value = getValue({ $, el }, { selector, exist: true });

expect(value).to.deep.equal(false);
});
Expand Down
3 changes: 1 addition & 2 deletions tests/parseSelector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ describe('parseSelector Tests', () => {
const value = parseSelector(selector);
expect({
selector: '.parent div',
type: 'array',
methods: []
type: 'array'
}).to.deep.equal(value);
});

Expand Down
Loading

0 comments on commit f85e4b2

Please sign in to comment.