diff --git a/src/helpers/String.ts b/src/helpers/String.ts index c02f276..d265da0 100644 --- a/src/helpers/String.ts +++ b/src/helpers/String.ts @@ -230,4 +230,41 @@ export class String extends Macroable { return `${value}th` } } + + /** + * Check if at least one of the provided search strings + * is included in the given value. + * + * @example + * ```ts + * String.includesSome('Hello model.id', 'models.id', 'models.provider') // false + * String.includesSome('Hello models.id', ['models.id', 'provider']) // true (models.id is found) + * ``` + */ + public static includesSome( + value: string, + ...searches: (string | string[])[] + ): boolean { + const terms = Array.isArray(searches[0]) ? (searches[0] as string[]) : (searches as string[]) + return terms.some(term => value.includes(term)) + } + + /** + * Check if every provided search string is included + * in the given value. + * + * @example + * ```ts + * String.includesEvery('Hello model.id', 'models.id', 'models.provider') // false + * String.includesEvery('Hello model.id', ['model.id', 'Hello']) // true (both are found) + * ``` + */ + public static includesEvery( + value: string, + ...searches: (string | string[])[] + ): boolean { + const terms = Array.isArray(searches[0]) ? (searches[0] as string[]) : (searches as string[]) + return terms.every(term => value.includes(term)) + } + } diff --git a/tests/unit/helpers/StringTest.ts b/tests/unit/helpers/StringTest.ts index 954375b..9f50da7 100644 --- a/tests/unit/helpers/StringTest.ts +++ b/tests/unit/helpers/StringTest.ts @@ -122,4 +122,50 @@ export default class StringTest { assert.throws(useCase, OrdinalNanException) } + + @Test() + public async shouldReturnTrueIfAtLeastOneTermMatchesUsingMultipleParams({ assert }: Context) { + const base = 'Hello model.id and some other text' + + assert.isTrue(String.includesSome(base, 'model.id', 'nope')) + assert.isTrue(String.includesSome(base, 'some', 'anything')) + assert.isFalse(String.includesSome(base, 'not-found', 'nope')) + } + + @Test() + public async shouldReturnTrueIfAtLeastOneTermMatchesUsingAnArray({ assert }: Context) { + const base = 'Hello model.id and some other text' + + assert.isTrue(String.includesSome(base, ['model.id', 'random'])) + assert.isFalse(String.includesSome(base, ['aaa', 'bbb'])) + } + + @Test() + public async shouldReturnFalseForIncludesSomeWithEmptyTerms({ assert }: Context) { + assert.isFalse(String.includesSome('anything')) + assert.isFalse(String.includesSome('anything', [])) + } + + @Test() + public async shouldReturnTrueOnlyIfAllTermsMatchUsingMultipleParams({ assert }: Context) { + const base = 'Hello model.id and some text' + + assert.isFalse(String.includesEvery(base, 'Hello', 'somethingElse')) + assert.isTrue(String.includesEvery(base, 'Hello', 'model.id')) + assert.isFalse(String.includesEvery(base, 'model.id', 'not-found')) + } + + @Test() + public async shouldReturnTrueOnlyIfAllTermsMatchUsingAnArray({ assert }: Context) { + const base = 'Hello model.id and some text' + + assert.isTrue(String.includesEvery(base, ['Hello', 'model.id'])) + assert.isFalse(String.includesEvery(base, ['Hello', 'random'])) + } + + @Test() + public async shouldReturnTrueForIncludesEveryWithEmptyTerms({ assert }: Context) { + assert.isTrue(String.includesEvery('anything')) + assert.isTrue(String.includesEvery('anything', [])) + } }