diff --git a/src/Camel-Case-Matching-Tests/CoGlobalEntryTest.class.st b/src/Camel-Case-Matching-Tests/CoGlobalEntryTest.class.st new file mode 100644 index 0000000..432b4a7 --- /dev/null +++ b/src/Camel-Case-Matching-Tests/CoGlobalEntryTest.class.st @@ -0,0 +1,120 @@ +Class { + #name : 'CoGlobalEntryTest', + #superclass : 'TestCase', + #category : 'Camel-Case-Matching-Tests', + #package : 'Camel-Case-Matching-Tests' +} + +{ #category : 'testing' } +CoGlobalEntryTest >> testCamelCasePartsOf [ + self assert: (CoGlobalEntry new camelCasePartsOf: 'CoGlobalVariableFetcher') + equals: #('Co' 'Global' 'Variable' 'Fetcher') +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenEmptyToken [ + +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenEmptyTokenWithParts [ + self assert:(CoGlobalEntry new matchToken: '' againstParts: #('foo' 'bar') partIndex: 1) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenExactMatch [ + self assert:(CoGlobalEntry new matchToken: 'FooBarBaz' againstParts: #('Foo' 'Bar' 'Baz') partIndex: 1) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenNoMatch [ + self assert:(CoGlobalEntry new matchToken: 'FooBarBaz' againstParts: #('Co' 'A' 'S' 'T' 'Fetcher') partIndex: 1) equals: false +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenTokenConsumesBeforePartsEnd [ + self assert:(CoGlobalEntry new matchToken: 'CoAST' againstParts: #('Co' 'A' 'S' 'T' 'Fetcher') partIndex: 1) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchTokenAgainstPartsPartIndexWhenTokenTooLong [ + self assert:(CoGlobalEntry new matchToken: 'FooBarBaz' againstParts: #('Foo' 'Bar') partIndex: 1) equals: false +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchesCamelCaseCompletionTokenCaseSensitiveWhenEmptyToken [ + self assert: (CoGlobalEntry new matchesCamelCaseCompletionToken: '' caseSensitive: true) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchesCamelCaseCompletionTokenCaseSensitiveWhenExactPrefixMatch [ + | entry | + entry := CoGlobalEntry new. + entry contents: 'CoGlobalVariableFetcher'. + + self assert: ( + entry matchesCamelCaseCompletionToken: 'CoGlo' + caseSensitive: true + ) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchesCamelCaseCompletionTokenCaseSensitiveWhenExactPrefixMatchCaseInsensitive [ + | entry | + entry := CoGlobalEntry new. + entry contents: 'CoGlobalVariableFetcher'. + + self assert: ( + entry matchesCamelCaseCompletionToken: 'CoGlo' + caseSensitive: false + ) equals: true +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchesCamelCaseCompletionTokenCaseSensitiveWhenMatchFailsDueToWrongOrder [ + | entry | + entry := CoGlobalEntry new. + entry contents: 'CoGlobalVariableFetcher'. + + self assert: ( + entry matchesCamelCaseCompletionToken: 'CoFetVar' + caseSensitive: false + ) equals: false +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testMatchesCamelCaseCompletionTokenCaseSensitiveWhenNoPartsReturnsFalse [ + | entry | + entry := CoGlobalEntry new. + entry contents: ''. + + self assert: ( + entry matchesCamelCaseCompletionToken: 'CoFetVar' + caseSensitive: false + ) equals: false +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testcamelCasePartsOfWhenAcronymInMiddle [ + self assert: (CoGlobalEntry new camelCasePartsOf: 'CoHeuristicASTResultSetBuilder') equals: #('Co' 'Heuristic' 'A' 'S' 'T' 'Result' 'Set' 'Builder') +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testcamelCasePartsOfWhenAllUppercase [ + self assert: (CoGlobalEntry new camelCasePartsOf: 'AST') equals: #('A' 'S' 'T') +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testcamelCasePartsOfWhenCamelCase [ + self assert: (CoGlobalEntry new camelCasePartsOf: 'CoVariableFetcher') equals: #('Co' 'Variable' 'Fetcher') +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testcamelCasePartsOfWhenEmptyString [ + self assert: (CoGlobalEntry new camelCasePartsOf: '') equals: #() +] + +{ #category : 'testing' } +CoGlobalEntryTest >> testcamelCasePartsOfWhenLowerCaseWord [ + self assert: (CoGlobalEntry new camelCasePartsOf: 'foo') equals: #('foo') +] diff --git a/src/Camel-Case-Matching-Tests/CoGlobalVariableFetcherTest.class.st b/src/Camel-Case-Matching-Tests/CoGlobalVariableFetcherTest.class.st new file mode 100644 index 0000000..5ea3a0e --- /dev/null +++ b/src/Camel-Case-Matching-Tests/CoGlobalVariableFetcherTest.class.st @@ -0,0 +1,27 @@ +Class { + #name : 'CoGlobalVariableFetcherTest', + #superclass : 'TestCase', + #category : 'Camel-Case-Matching-Tests', + #package : 'Camel-Case-Matching-Tests' +} + +{ #category : 'testing' } +CoGlobalVariableFetcherTest >> testNewEntryForSetsContents [ + |fetcher| + fetcher := CoGlobalVariableFetcher new. + self assert: ((fetcher newEntryFor: 'OrderedCollection') contents) equals: 'OrderedCollection' +] + +{ #category : 'testing' } +CoGlobalVariableFetcherTest >> testNewEntryForSetsFetcherName [ + |fetcher| + fetcher := CoGlobalVariableFetcher new. + self assert: ((fetcher newEntryFor: 'OrderedCollection') fetcherName ) equals: 'CoGlobalVariableFetcher' +] + +{ #category : 'testing' } +CoGlobalVariableFetcherTest >> testNewEntryForSetsNode [ + |fetcher| + fetcher := CoGlobalVariableFetcher new. + self assert: ((fetcher newEntryFor: 'OrderedCollection') node) equals: nil +] diff --git a/src/Camel-Case-Matching/CoCaseInsensitiveBeginsWithFilter.extension.st b/src/Camel-Case-Matching/CoCaseInsensitiveBeginsWithFilter.extension.st index e803d7f..333b0c9 100644 --- a/src/Camel-Case-Matching/CoCaseInsensitiveBeginsWithFilter.extension.st +++ b/src/Camel-Case-Matching/CoCaseInsensitiveBeginsWithFilter.extension.st @@ -3,7 +3,6 @@ Extension { #name : 'CoCaseInsensitiveBeginsWithFilter' } { #category : '*Camel-Case-Matching' } CoCaseInsensitiveBeginsWithFilter >> accepts: aCandidate [ - ^ (self candidate: aCandidate matchesPrefixCaseSensitive: false) - or: [ NECPreferences camelCaseGlobalMatching - and: [ self candidate: aCandidate matchesCamelCaseCaseSensitive: false ] ] + ^ (self candidate: aCandidate matchesPrefixCaseSensitive: false) or: [ + self candidate: aCandidate matchesCamelCaseCaseSensitive: false ] ] diff --git a/src/Camel-Case-Matching/CoEntry.extension.st b/src/Camel-Case-Matching/CoEntry.extension.st index aa8100b..70559dc 100644 --- a/src/Camel-Case-Matching/CoEntry.extension.st +++ b/src/Camel-Case-Matching/CoEntry.extension.st @@ -2,18 +2,22 @@ Extension { #name : 'CoEntry' } { #category : '*Camel-Case-Matching' } CoEntry >> beginsWith: aString [ - + "Returns true if the receiver begins with the given string using case-sensitive prefix matching." ^ self matchesPrefixToken: aString caseSensitive: true ] { #category : '*Camel-Case-Matching' } CoEntry >> matchesCamelCaseCompletionToken: aString caseSensitive: aBoolean [ - + "Default implementation always returns false. + Actual camelCase matching logic is implemented in subclasses." + ^ false ] { #category : '*Camel-Case-Matching' } CoEntry >> matchesPrefixToken: aString caseSensitive: aBoolean [ + "Returns true if the receiver's contents begins with aString, + using either case-sensitive or case-insensitive comparison." ^ self contents beginsWith: aString caseSensitive: aBoolean ] diff --git a/src/Camel-Case-Matching/CoGlobalEntry.extension.st b/src/Camel-Case-Matching/CoGlobalEntry.extension.st index b24f0ba..4ff9f84 100644 --- a/src/Camel-Case-Matching/CoGlobalEntry.extension.st +++ b/src/Camel-Case-Matching/CoGlobalEntry.extension.st @@ -2,6 +2,9 @@ Extension { #name : 'CoGlobalEntry' } { #category : '*Camel-Case-Matching' } CoGlobalEntry >> camelCasePartsOf: aString [ + "Splits a camelCase or PascalCase string into its component parts. + Returns an array of substrings, breaking before each uppercase letter + (except the first character)." | parts current | parts := OrderedCollection new. @@ -21,6 +24,10 @@ CoGlobalEntry >> camelCasePartsOf: aString [ { #category : '*Camel-Case-Matching' } CoGlobalEntry >> matchToken: token againstParts: parts [ +"Entry point for token matching against a collection of parts. + Starts the recursive matching process from the first part (index 1). + See matchToken:againstParts:partIndex: +" ^ self matchToken: token @@ -31,6 +38,15 @@ CoGlobalEntry >> matchToken: token againstParts: parts [ { #category : '*Camel-Case-Matching' } CoGlobalEntry >> matchToken: token againstParts: parts partIndex: startIndex [ +"Returns true if the given token can be matched by concatenating + prefixes of successive parts, starting at startIndex. + + The match proceeds in order through the parts collection, taking + one prefix per part and consuming the token progressively. + Uses backtracking to try all possible prefix lengths. + + Returns true if the entire token is consumed, false otherwise." + token ifEmpty: [ ^ true ]. startIndex > parts size ifTrue: [ ^ false ]. @@ -54,6 +70,13 @@ CoGlobalEntry >> matchToken: token againstParts: parts partIndex: startIndex [ { #category : '*Camel-Case-Matching' } CoGlobalEntry >> matchesCamelCaseCompletionToken: aString caseSensitive: aBoolean [ +"Checks whether aString matches the receiver's contents + + The contents are split into camelCase parts, and the input string + is compared as a prefix across these parts in order. + + Returns true if the token can be matched, false otherwise." + | token parts normalizedParts normalizedToken | aString ifEmpty: [ ^ true ]. diff --git a/src/Camel-Case-Matching/CoGlobalVariableFetcher.extension.st b/src/Camel-Case-Matching/CoGlobalVariableFetcher.extension.st index 765d936..72dbc85 100644 --- a/src/Camel-Case-Matching/CoGlobalVariableFetcher.extension.st +++ b/src/Camel-Case-Matching/CoGlobalVariableFetcher.extension.st @@ -2,6 +2,8 @@ Extension { #name : 'CoGlobalVariableFetcher' } { #category : '*Camel-Case-Matching' } CoGlobalVariableFetcher >> entriesDo: aBlock [ +"Iterates over full environment entries and filtered global names, +converting each into a CoGlobalEntry and passing it to the block." self entriesDoWithFullEnvironmentScan: aBlock . @@ -13,6 +15,9 @@ CoGlobalVariableFetcher >> entriesDo: aBlock [ { #category : '*Camel-Case-Matching' } CoGlobalVariableFetcher >> entriesDoWithFullEnvironmentScan: aBlock [ +"Iterates over all global system names and yields a CoGlobalEntry for each one to the given block. + +Performs a full environment scan (no filtering) and wraps each global name into an entry before passing it to the block." self systemNavigation allGlobalNamesStartingWith: '' @@ -23,6 +28,8 @@ CoGlobalVariableFetcher >> entriesDoWithFullEnvironmentScan: aBlock [ { #category : '*Camel-Case-Matching' } CoGlobalVariableFetcher >> newEntryFor: aGlobalName [ +"Creates a CoGlobalEntry for a global name, setting its AST node and fetcher name." + ^ (CoGlobalEntry contents: aGlobalName node: astNode) fetcherName: self class name; yourself