Skip to content

Commit

Permalink
Merge pull request #759 from jecisc/protocols
Browse files Browse the repository at this point in the history
Add StProtocolNameChooserPresenter
  • Loading branch information
Ducasse authored Jun 11, 2024
2 parents 5f59db6 + 328bd05 commit 4ee54dc
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 21 deletions.
14 changes: 5 additions & 9 deletions src/BaselineOfNewTools/BaselineOfNewTools.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ BaselineOfNewTools >> baseline: spec [

spec
package: 'NewTools-Core';
package: 'NewTools-Core-Tests' with: [ spec requires: #('NewTools-Core') ];
package: 'NewTools-Morphic';
package: 'NewTools-Gtk';
"Basic tools (inherited from Spec)"
Expand Down Expand Up @@ -81,7 +82,6 @@ BaselineOfNewTools >> baseline: spec [
"Fuel"
package: 'NewTools-Debugger-Fuel';
package: 'NewTools-Debugger-Fuel-Tests' with: [ spec requires: #( 'NewTools-Debugger-Fuel' ) ];
package: 'NewTools-Fuel';
"Rewriter Tools"
package: 'NewTools-RewriterTools-Backend';
package: 'NewTools-RewriterTools' with: [ spec requires: #('NewTools-RewriterTools-Backend') ];
Expand All @@ -104,10 +104,10 @@ BaselineOfNewTools >> baseline: spec [
package: 'NewTools-SettingsBrowser' with: [ spec requires: #('ColorPicker') ];
package: 'NewTools-SettingsBrowser-Tests' with: [ spec requires: #('NewTools-SettingsBrowser') ];

package: 'NewTools-Compression-Utils' with: [ spec requires: #('NewTools-FileBrowser') ].
package: 'NewTools-Utils' with: [ spec requires: #('NewTools-FileBrowser') ].

spec
group: 'Core' with: #( 'NewTools-Core' 'NewTools-Morphic' );
group: 'Core' with: #( 'NewTools-Core' 'NewTools-Core-Tests' 'NewTools-Morphic' );
group: 'Playground' with: #( 'Core' 'NewTools-Playground' 'NewTools-Playground-Tests' );
group: 'Inspector' with: #( 'Core' 'NewTools-Inspector' 'NewTools-Inspector-Tests' );
group: 'Debugger' with: #(
Expand All @@ -124,7 +124,7 @@ BaselineOfNewTools >> baseline: spec [
'NewTools-Debugger-Tests'
'NewTools-Debugger-Fuel'
'NewTools-Debugger-Fuel-Tests'
'NewTools-Fuel'
'NewTools-Utils'
'NewTools-DebugPointsBrowser'
'NewTools-ObjectCentricDebugPoints' );
group: 'Spotter' with: #(
Expand Down Expand Up @@ -172,9 +172,6 @@ BaselineOfNewTools >> baseline: spec [
group: 'SettingsBrowser' with: #(
'NewTools-SettingsBrowser'
'NewTools-SettingsBrowser-Tests');
"Compression Utilities"
group: 'CompressionUtilities' with: #(
'NewTools-Compression-Utils');

group: 'default' with: #(
'Playground'
Expand All @@ -190,8 +187,7 @@ BaselineOfNewTools >> baseline: spec [
'FileBrowser'
'Finder'
'Profiler'
'SettingsBrowser'
'CompressionUtilities') ]
'SettingsBrowser' ) ]
]

{ #category : 'external projects' }
Expand Down
1 change: 0 additions & 1 deletion src/NewTools-Compression-Utils/package.st

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"
A StProtocolNameChooserPresenterTest is a test class for testing the behavior of StProtocolNameChooserPresenter
"
Class {
#name : 'StProtocolNameChooserPresenterTest',
#superclass : 'TestCase',
#instVars : [
'presenter'
],
#category : 'NewTools-Core-Tests-ProtocolChooser',
#package : 'NewTools-Core-Tests',
#tag : 'ProtocolChooser'
}

{ #category : 'running' }
StProtocolNameChooserPresenterTest >> setUp [
super setUp.
presenter := StProtocolNameChooserPresenter new
]

{ #category : 'tests' }
StProtocolNameChooserPresenterTest >> testSmokeTest [

| window |
[ self shouldnt: [ window := presenter open ] raise: Error ] ensure: [ window close ].

[ self shouldnt: [ window := presenter openDialog ] raise: Error ] ensure: [ window close ].

presenter concernedClass: self class.
presenter protocolName: 'test'.

[ self shouldnt: [ window := presenter open ] raise: Error ] ensure: [ window close ]
]

{ #category : 'tests' }
StProtocolNameChooserPresenterTest >> testSuggestedProtocolsAreOrderedByPriority [
"I'm not sure how to test this without using the sae code as #protocolsToSuggest so I'm hardcoding 3 of the most used protocols in the system"

self assert: ((presenter protocolsToSuggest first: 5) includesAll: #( accessing initialization testing ))
]

{ #category : 'tests' }
StProtocolNameChooserPresenterTest >> testSuggestedProtocolsDependOnInstanceOrClassSide [

| protocolName classProtocolName |
protocolName := UUID new asString36.
classProtocolName := UUID new asString36.

[
self class addProtocol: protocolName.
self class class addProtocol: classProtocolName.

presenter concernedClass: self class.
self assert: (presenter protocolsToSuggest includes: protocolName).
self deny: (presenter protocolsToSuggest includes: classProtocolName).

presenter concernedClass: self class class.
self deny: (presenter protocolsToSuggest includes: protocolName).
self assert: (presenter protocolsToSuggest includes: classProtocolName) ] ensure: [
self class removeProtocol: protocolName.
self class class removeProtocol: classProtocolName ]
]

{ #category : 'tests' }
StProtocolNameChooserPresenterTest >> testSuggestedProtocolsIncludesProtocolsOfTheImage [

| protocolName |
protocolName := UUID new asString36.

self deny: (presenter protocolsToSuggest includes: protocolName).
[
self class addProtocol: protocolName.

self assert: (presenter protocolsToSuggest includes: protocolName) ] ensure: [ self class removeProtocol: protocolName ]
]
1 change: 1 addition & 0 deletions src/NewTools-Core-Tests/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : 'NewTools-Core-Tests' }
165 changes: 165 additions & 0 deletions src/NewTools-Core/StProtocolNameChooserPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
"
I am a little interface to let the user choose the name of a protocol.
This interface will suggest the name of the protocol as the user types the beginning of the name.
I can be configured with a concerned class to refine the UI such as proposing instance or class side protocols in the suggestion list.
See my class side for an example of usage and some helpers.
Idea of improvements for the future:
- Suggest protocols from super classes first?
- Add tests
"
Class {
#name : 'StProtocolNameChooserPresenter',
#superclass : 'StPresenter',
#instVars : [
'suggestionList',
'protocolNameField',
'concernedClass'
],
#category : 'NewTools-Core-ProtocolChooser',
#package : 'NewTools-Core',
#tag : 'ProtocolChooser'
}

{ #category : 'examples' }
StProtocolNameChooserPresenter class >> exampleConfiguringPresenter [

<example>
self requestProtocolNameConfiguring: [ :presenter :dialog |
presenter
concernedClass: self class; "Giving the concerned class can allow some customizations such as knowing if we should suggest instance or class side protocols"
protocolName: 'ac'.
dialog title: 'Updated title' ]
]

{ #category : 'instance creation' }
StProtocolNameChooserPresenter class >> open [

<script>
self new open
]

{ #category : 'instance creation' }
StProtocolNameChooserPresenter class >> requestProtocolName [
"See comment of StProtocolNameChooser class>>#requestProtocolNameConfiguring:"

<script>
^ self requestProtocolNameConfiguring: [ :presenter :dialog | ]
]

{ #category : 'instance creation' }
StProtocolNameChooserPresenter class >> requestProtocolNameConfiguring: aBlock [
"I request a protocol name through a dialog and signal a CmdCommandAborted in case the provided protocol is empty or an extension name.
I allow the user to configure the presenter or the dialog via a configuration block."

<script>
| protocolName presenter dialog |
dialog := (presenter := self new) asBlockedDialogWindow.

aBlock cull: presenter cull: dialog.

dialog open.

protocolName := presenter protocolName.

protocolName isEmptyOrNil ifTrue: [ CmdCommandAborted signal ].
(protocolName beginsWith: '*') ifTrue: [
self inform: 'Star is forbidden for protocol name since this is used for method extensions.'.
^ CmdCommandAborted signal ].
^ protocolName
]

{ #category : 'accessing' }
StProtocolNameChooserPresenter >> concernedClass [
"Giving the concerned class can allow some customizations such as knowing if we should suggest instance or class side protocols"

^ concernedClass
]

{ #category : 'accessing' }
StProtocolNameChooserPresenter >> concernedClass: anObject [

concernedClass := anObject
]

{ #category : 'initialization' }
StProtocolNameChooserPresenter >> connectPresenters [

super connectPresenters.

protocolNameField whenTextChangedDo: [ self updatePresenter ]
]

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

^ SpBoxLayout newTopToBottom
add: suggestionList;
add: protocolNameField expand: false;
yourself
]

{ #category : 'initialization' }
StProtocolNameChooserPresenter >> initializeDialogWindow: aDialogWindowPresenter [

super initializeDialogWindow: aDialogWindowPresenter.
protocolNameField whenSubmitDo: [ :protocolName | aDialogWindowPresenter triggerOkAction ].
suggestionList whenSelectedDo: [ :protocolName | self protocolName: protocolName ]
]

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

super initializePresenters.

suggestionList := self newList.

protocolNameField := self newTextInput.
protocolNameField placeholder: 'Protocol name (e.g. accessing)'
]

{ #category : 'initialization' }
StProtocolNameChooserPresenter >> initializeWindow: aWindowPresenter [

super initializeWindow: aWindowPresenter.
aWindowPresenter title: 'New protocol name'.

aWindowPresenter whenOpenedDo: [ protocolNameField takeKeyboardFocus ]
]

{ #category : 'accessing - defaults' }
StProtocolNameChooserPresenter >> protocolName [
^ protocolNameField text asSymbol
]

{ #category : 'accessing' }
StProtocolNameChooserPresenter >> protocolName: aString [
"I allow to set a default protocol name to the list."

protocolNameField text: aString.
self updatePresenter
]

{ #category : 'initialization' }
StProtocolNameChooserPresenter >> protocolsToSuggest [

| suggestedProtocols |
suggestedProtocols := concernedClass environment allClasses flatCollect: [ :class |
(concernedClass isNil or: [ concernedClass isInstanceSide ])
ifTrue: [ class protocols ]
ifFalse: [ class class protocols ] ].
suggestedProtocols := suggestedProtocols reject: [ :protocol | protocol isExtensionProtocol ].
suggestedProtocols := suggestedProtocols collect: [ :protocol | protocol name ] as: Bag.
suggestedProtocols := suggestedProtocols sortedCounts collect: [ :association | association value ].
suggestedProtocols := suggestedProtocols select: [ :protocolName | protocolName includesSubstring: self protocolName ].
^ suggestedProtocols
]

{ #category : 'initialization' }
StProtocolNameChooserPresenter >> updatePresenter [

suggestionList items: self protocolsToSuggest
]
1 change: 0 additions & 1 deletion src/NewTools-Fuel/package.st

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Class {
#instVars : [
'files'
],
#category : 'NewTools-Fuel-CommandLineHandler',
#package : 'NewTools-Fuel',
#tag : 'CommandLineHandler'
#category : 'NewTools-Utils-Fuel',
#package : 'NewTools-Utils',
#tag : 'Fuel'
}

{ #category : 'accessing' }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Extension { #name : 'FLMaterializer' }

{ #category : '*NewTools-Fuel-FileRegistry' }
{ #category : '*NewTools-Utils-Fuel-FileRegistry' }
FLMaterializer class >> fileReaderServicesForFile: fullName suffix: suffix [
<fileService>
suffix = 'fuel'
ifFalse: [ ^ #() ].
^ { self serviceFuelMaterialize }
]

{ #category : '*NewTools-Fuel-FileRegistry' }
{ #category : '*NewTools-Utils-Fuel-FileRegistry' }
FLMaterializer class >> inspectMaterializationFromFileNamed: aString [
| result |
result := self new
Expand All @@ -17,7 +17,7 @@ FLMaterializer class >> inspectMaterializationFromFileNamed: aString [
^ result inspect
]

{ #category : '*NewTools-Fuel-FileRegistry' }
{ #category : '*NewTools-Utils-Fuel-FileRegistry' }
FLMaterializer class >> serviceFuelMaterialize [
^ SimpleServiceEntry
provider: self
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Extension { #name : 'InflateStream' }

{ #category : '*NewTools-Compression-Utils' }
{ #category : '*NewTools-Utils-Compression' }
InflateStream class >> openWithContents: contentsString label: titleString [
"Open a text viewer on contentsString and window label titleString"

Expand All @@ -13,7 +13,7 @@ InflateStream class >> openWithContents: contentsString label: titleString [
extent: 600 @ 800 ]
]

{ #category : '*NewTools-Compression-Utils' }
{ #category : '*NewTools-Utils-Compression' }
InflateStream class >> viewContents: fullFileName [
"Open the decompressed contents of fullFileName"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Extension { #name : 'Object' }

{ #category : '*NewTools-Fuel' }
{ #category : '*NewTools-Utils-Fuel' }
Object >> fuelOut [
| target |
target := FileLocator imageDirectory / self printString asFileName, 'fuel'.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Extension { #name : 'ZipArchive' }

{ #category : '*NewTools-Compression-Utils' }
{ #category : '*NewTools-Utils-Compression' }
ZipArchive class >> extractAllIn: aFileReferenceOrFileName [
"Service method to extract all contents of a zip.
Example:
Expand Down
1 change: 1 addition & 0 deletions src/NewTools-Utils/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : 'NewTools-Utils' }

0 comments on commit 4ee54dc

Please sign in to comment.