Skip to content

Commit

Permalink
Merge pull request #1607 from hernanmd/add_search_input_presenter
Browse files Browse the repository at this point in the history
Add Options presenter for text search input fields
  • Loading branch information
Ducasse authored Sep 21, 2024
2 parents 5b6ba6a + eca79a2 commit eca5e00
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/Spec2-Core/SpAbstractFormButtonPresenter.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ SpAbstractFormButtonPresenter >> initialize [
self whenLabelClickableChangedDo: [ :aBoolean | self changed: {#labelClickable: . aBoolean} ]
]

{ #category : 'testing' }
SpAbstractFormButtonPresenter >> isActive [
"Answer <true> if the receiver is selected"

^ self state
]

{ #category : 'api' }
SpAbstractFormButtonPresenter >> label [
"Answers the label to be shown by the button"
Expand Down
124 changes: 124 additions & 0 deletions src/Spec2-Core/SpSearchInputFieldOptionsPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"
Provides a presenter to allow the user to configure the type of search.
A radio button group is used for the main search type:
- Substring search
- Regular expression search
- Exact matching
A separate checkboxes is used for case sensitive search. It's important to note that exact matching cannot be combined with substring or regex searches, as they are fundamentally different approaches.
"
Class {
#name : 'SpSearchInputFieldOptionsPresenter',
#superclass : 'SpPresenter',
#instVars : [
'caseCheckBox',
'regexpOptionButton',
'exactOptionButton',
'substringOptionButton'
],
#category : 'Spec2-Core-Widgets',
#package : 'Spec2-Core',
#tag : 'Widgets'
}

{ #category : 'instance creation' }
SpSearchInputFieldOptionsPresenter class >> open [
<script>

^ self new open
]

{ #category : 'accessing' }
SpSearchInputFieldOptionsPresenter >> caseCheckBox [

^ caseCheckBox
]

{ #category : 'layout' }
SpSearchInputFieldOptionsPresenter >> defaultLayout [

^ SpBoxLayout newLeftToRight
spacing: 2;
add: substringOptionButton width: 95;
add: regexpOptionButton width: 70;
add: exactOptionButton width: 70;
add: caseCheckBox width: 70;
yourself
]

{ #category : 'accessing' }
SpSearchInputFieldOptionsPresenter >> exactOptionButton [

^ exactOptionButton
]

{ #category : 'initialization' }
SpSearchInputFieldOptionsPresenter >> initializePresenters [

super initializePresenters.
self initializeSearchTypePresenters.
]

{ #category : 'initialization' }
SpSearchInputFieldOptionsPresenter >> initializeSearchTypePresenters [

regexpOptionButton := self newRadioButton
label: 'Regexp';
state: false;
help: 'Use regular expression. For instance, use ^AB(.*)$ to match anything begining with AB';
yourself.

exactOptionButton := self newRadioButton
label: 'Exact';
state: false;
help: 'Use exact match';
yourself.

substringOptionButton := self newRadioButton
label: 'Substring';
help: 'Use substring search';
yourself.

substringOptionButton associatedRadioButtons: { exactOptionButton. regexpOptionButton }.

caseCheckBox := self newCheckBox
label: 'Case';
state: false;
help: 'Use match case';
yourself.
]

{ #category : 'accessing' }
SpSearchInputFieldOptionsPresenter >> regexpOptionButton [

^ regexpOptionButton
]

{ #category : 'updating' }
SpSearchInputFieldOptionsPresenter >> selectBlock [
"Answer a <BlockClosure> with the matching strategy depending of the active searching options in the receiver"

(regexpOptionButton isActive and: [ caseCheckBox isActive ])
ifTrue: [ ^ [ : item : regex | regex asRegex search: item ] ].
(regexpOptionButton isActive and: [ caseCheckBox isActive not ])
ifTrue: [ ^ [ : item : regex | regex asRegexIgnoringCase search: item ] ].

(exactOptionButton isActive and: [ caseCheckBox isActive])
ifTrue: [ ^ [ : item : pattern | item = pattern ] ].
(exactOptionButton isActive and: [ caseCheckBox isActive not ])
ifTrue: [ ^ [ : item : pattern | item asLowercase = pattern asLowercase ] ].

(substringOptionButton isActive and: [ caseCheckBox isActive ])
ifTrue: [ ^ [ : item : pattern | item includesSubstring: pattern caseSensitive: true ] ].
(substringOptionButton isActive and: [ caseCheckBox isActive not ])
ifTrue: [ ^ [ : item : pattern | item includesSubstring: pattern caseSensitive: false ] ].

]

{ #category : 'accessing' }
SpSearchInputFieldOptionsPresenter >> substringBox [
^ substringOptionButton
]
94 changes: 94 additions & 0 deletions src/Spec2-Tests/SpSearchInputFieldOptionsPresenterTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
Class {
#name : 'SpSearchInputFieldOptionsPresenterTest',
#superclass : 'SpBasePresenterTest',
#category : 'Spec2-Tests-Common-Widgets',
#package : 'Spec2-Tests',
#tag : 'Common-Widgets'
}

{ #category : 'accessing' }
SpSearchInputFieldOptionsPresenterTest >> classToTest [

^ SpSearchInputFieldOptionsPresenter
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockExactCaseInsensitive [

presenter exactOptionButton click.
self
assert: (presenter selectBlock value: 'ABC' value: 'abc')
description: 'It checks that exact and case-insensitive returns true for same letters with different case'
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockExactCaseSensitive [

presenter exactOptionButton click.
presenter caseCheckBox click.
self
deny: (presenter selectBlock value: 'ABC' value: 'abc')
description: 'It checks that exact and case-insensitive returns false for same letters with different case'.

self
assert: (presenter selectBlock value: 'ABC' value: 'ABC')
description: 'It checks that exact and case-insensitive returns false for same letters with equal case'.
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockRegexCaseInsensitive [

presenter regexpOptionButton click.

self
assert: (presenter selectBlock value: 'ABC' value: 'ABC')
description: 'It checks that exact and case-insensitive returns false for same letters with equal case'.

self
assert: (presenter selectBlock value: 'AbCD' value: '^AB(.*)$')
description: 'It checks that exact and case-insensitive returns false for same letters with equal case'.
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockRegexCaseSensitive [

presenter regexpOptionButton click.
presenter caseCheckBox click.

self
deny: (presenter selectBlock value: 'AbCD' value: '^AB(.*)$')
description: 'It checks that regular expression and case-insensitive returns false for same letters with different case'.

self
assert: (presenter selectBlock value: 'ABC' value: '^AB(.*)$')
description: 'It checks that regular expression and case-insensitive returns true for matching pattern with equal case'.
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockSubstringCaseInsensitive [

presenter substringBox click.

self
deny: (presenter selectBlock value: 'AbCDef' value: 'pspsp')
description: 'It checks that substring and case-insensitive returns false for different substring'.

self
assert: (presenter selectBlock value: 'ABCdef' value: 'cde')
description: 'It checks that substring and case-insensitive returns true for existing substring pattern'.
]

{ #category : 'tests' }
SpSearchInputFieldOptionsPresenterTest >> testSelectBlockSubstringCaseSensitive [

presenter substringBox click.
presenter caseCheckBox click.

self
deny: (presenter selectBlock value: 'AbCDef' value: 'cdE')
description: 'It checks that substring and case-sensitive returns false for same substring with different case'.

self
assert: (presenter selectBlock value: 'ABCdef' value: 'Cde')
description: 'It checks that substring and case-sensitive returns true for existing substring pattern with same case'.
]

0 comments on commit eca5e00

Please sign in to comment.