/** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: MPL-2.0 */ import matchGlob from 'nomad-ui/utils/match-glob'; import { module, test } from 'qunit'; module('Unit | Utility | match-glob', function () { module('#_doesMatchPattern', function () { const edgeCaseTest = 'this is a ϗѾ test'; module('base cases', function () { test('it handles an empty pattern', function (assert) { // arrange const pattern = ''; const emptyPath = ''; const nonEmptyPath = 'a'; // act const matchingResult = matchGlob(pattern, emptyPath); const nonMatchingResult = matchGlob(pattern, nonEmptyPath); // assert assert.ok(matchingResult, 'Empty pattern should match empty path'); assert.notOk( nonMatchingResult, 'Empty pattern should not match non-empty path' ); }); test('it handles an empty path', function (assert) { // arrange const emptyPath = ''; const emptyPattern = ''; const nonEmptyPattern = 'a'; // act const matchingResult = matchGlob(emptyPattern, emptyPath); const nonMatchingResult = matchGlob(nonEmptyPattern, emptyPath); // assert assert.ok(matchingResult, 'Empty path should match empty pattern'); assert.notOk( nonMatchingResult, 'Empty path should not match non-empty pattern' ); }); test('it handles a pattern without a glob', function (assert) { // arrange const path = '/foo'; const matchingPattern = '/foo'; const nonMatchingPattern = '/bar'; // act const matchingResult = matchGlob(matchingPattern, path); const nonMatchingResult = matchGlob(nonMatchingPattern, path); // assert assert.ok(matchingResult, 'Matches path correctly.'); assert.notOk(nonMatchingResult, 'Does not match non-matching path.'); }); test('it handles a pattern that is a lone glob', function (assert) { // arrange const path = '/foo'; const glob = '*'; // act const matchingResult = matchGlob(glob, path); // assert assert.ok(matchingResult, 'Matches glob.'); }); test('it matches on leading glob', function (assert) { // arrange const pattern = '*bar'; const matchingPath = 'footbar'; const nonMatchingPath = 'rockthecasba'; // act const matchingResult = matchGlob(pattern, matchingPath); const nonMatchingResult = matchGlob(pattern, nonMatchingPath); // assert assert.ok( matchingResult, 'Correctly matches when leading glob and matching path.' ); assert.notOk( nonMatchingResult, 'Does not match when leading glob and non-matching path.' ); }); test('it matches on trailing glob', function (assert) { // arrange const pattern = 'foo*'; const matchingPath = 'footbar'; const nonMatchingPath = 'bar'; // act const matchingResult = matchGlob(pattern, matchingPath); const nonMatchingResult = matchGlob(pattern, nonMatchingPath); // assert assert.ok(matchingResult, 'Correctly matches on trailing glob.'); assert.notOk( nonMatchingResult, 'Does not match on trailing glob if pattern does not match.' ); }); test('it matches when glob is in middle', function (assert) { // arrange const pattern = 'foo*bar'; const matchingPath = 'footbar'; const nonMatchingPath = 'footba'; // act const matchingResult = matchGlob(pattern, matchingPath); const nonMatchingResult = matchGlob(pattern, nonMatchingPath); // assert assert.ok( matchingResult, 'Correctly matches on glob in middle of path.' ); assert.notOk( nonMatchingResult, 'Does not match on glob in middle of path if not full pattern match.' ); }); }); module('matching edge cases', function () { test('it matches when string is between globs', function (assert) { // arrange const pattern = '*is *'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles many non-consective globs', function (assert) { // arrange const pattern = '*is*a*'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles double globs', function (assert) { // arrange const pattern = '**test**'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles many consecutive globs', function (assert) { // arrange const pattern = '**is**a***test*'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles white space between globs', function (assert) { // arrange const pattern = '* *'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles a pattern of only globs', function (assert) { // arrange const pattern = '**********'; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles unicode characters', function (assert) { // arrange const pattern = `*Ѿ*`; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); test('it handles mixed ASCII codes', function (assert) { // arrange const pattern = `*is a ϗѾ *`; // act const result = matchGlob(pattern, edgeCaseTest); // assert assert.ok(result); }); }); module('non-matching edge cases', function () { const failingCases = [ { case: 'test*', message: 'Implicit substring match', }, { case: '*is', message: 'Parial match', }, { case: '*no*', message: 'Globs without match between them', }, { case: ' ', message: 'Plain white space', }, { case: '* ', message: 'Trailing white space', }, { case: ' *', message: 'Leading white space', }, { case: '*ʤ*', message: 'Non-matching unicode', }, { case: 'this*this is a test', message: 'Repeated prefix', }, ]; failingCases.forEach(({ case: failingPattern, message }) => { test('should fail the specified cases', function (assert) { const result = matchGlob(failingPattern, edgeCaseTest); assert.notOk(result, `${message} should not match.`); }); }); }); }); });