CustomMenuBuilderTests.st
author Jakub Nesveda <jakubnesveda@seznam.cz>
Sun, 04 Jan 2015 16:00:31 +0100
changeset 796 1e98cf455d2d
parent 795 944c5812e702
child 803 95cdac772759
permissions -rw-r--r--
More error prone CustomMenuBuilder

"{ Package: 'jn:refactoring_custom' }"

TestCase subclass:#CustomMenuBuilderTests
	instanceVariableNames:'builder menu provider manager mock generatorClassMock resources'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Refactoring-Custom-UI-Tests'
!


!CustomMenuBuilderTests methodsFor:'initialization & release'!

setUp
    super setUp.

    menu := Menu labels: 'Label_01
Label_02
Label_03' values: nil.

    mock := CustomMock new.

    provider := mock mockOf: OrderedCollection.
    provider compileMockMethod: 'generatorsAndRefactoringsDo: aBlock
        self do: aBlock'.  

    manager := CustomManager new.
    manager generatorsOrRefactoringsProvider: provider.

    builder := CustomMenuBuilder new.
    builder manager: manager.

    generatorClassMock := mock mockClassOf: Object.
    mock createMockGetters: generatorClassMock forSelectors: {
        'label'. 'group'. 'isAbstract'. 'availableInContext:'. 
        'availableInPerspective:'. 'availableForProgrammingLanguagesInContext:'
    }.

    resources := mock mockOf: Object.
    resources compileMockMethod: 'string:aString ^ ''Translated '', aString'.

    "Modified: / 28-12-2014 / 22:50:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

tearDown

    mock unmockAll.
    
    super tearDown.

    "Modified: / 28-12-2014 / 22:02:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilderTests methodsFor:'private'!

addGenerator: aLabel group: aGroup
    "Creates initialized code generator mock and adds it to managers generators"
    | generator |

    generator := generatorClassMock new
        objectAttributeAt: #isAbstract put: false;
        objectAttributeAt: #label put: aLabel;
        objectAttributeAt: #group put: aGroup;
        objectAttributeAt: #availableInContext: put: true;
        objectAttributeAt: #availableInPerspective: put: true;
        objectAttributeAt: #availableForProgrammingLanguagesInContext: put: true;
        yourself.

    manager generatorsOrRefactoringsProvider add: generator.

    ^ generator

    "Created: / 28-12-2014 / 22:10:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

menuItemLabels
    "Helper which returns labels from menu item as collection as string.
    We are comparing labels, because menu items are not comparable - 
    MenuItem label: 'Label' not equals MenuItem label: 'Label'"

    ^ (OrderedCollection streamContents: [ :stream |
        menu itemsDo: [ :item |
            stream nextPut: item label.
            item submenuChannel notNil ifTrue: [ 
                stream nextPut: (OrderedCollection streamContents: [ :innerStream |
                    item submenuChannel value itemsDo: [ :innerItem |
                        innerStream nextPut: innerItem label
                    ]
                ]) asArray
            ]
        ]
    ]) asArray

    "Created: / 28-12-2014 / 10:41:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
    "Modified: / 28-12-2014 / 23:17:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilderTests methodsFor:'tests'!

test_build_menu_empty
    | expectedMenu actualMenu |

    expectedMenu := {'Label_01'. 'Label_02'. 'Label_03'}.

    builder
        perspective: CustomPerspective classPerspective;
        menu: menu;
        submenuLabel: 'SomeLabel';
        buildMenu.    

    actualMenu := self menuItemLabels.

    self assert: expectedMenu = actualMenu

    "Modified: / 28-12-2014 / 22:41:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_build_menu_for_context_filter
    | expectedMenu actualMenu |

    (self
        addGenerator: 'Generator_01' group: #();
        addGenerator: 'Generator_02' group: #(Group_02);
        addGenerator: 'Generator_03' group: #();
        addGenerator: 'Generator_04' group: #(Group_01);
        addGenerator: 'Generator_05' group: #(Group_01 Subgroup_01);
        addGenerator: 'Generator_06' group: #(Group_01);
        addGenerator: 'Generator_07' group: #(Group_01 Subgroup_01))
            objectAttributeAt: #availableInContext: put: false. "To have at least one generator not avilable for context"

    "Not present generators"
    (self addGenerator: 'Generator_08' group: #())
        objectAttributeAt: #availableForProgrammingLanguagesInContext: put: false.
    (self addGenerator: 'Generator_09' group: #())
        objectAttributeAt: #availableInPerspective: put: false.
    self addGenerator: 'Generator_10' group: #().

    menu := builder buildMenuForContext: CustomSubContext new filter: [ :generator |
        generator label ~= 'Generator_10'
    ].

    expectedMenu := {
        'Generator_01'.
        'Generator_03'.
        '-'.
        'Generator_04'.
        'Generator_06'.
        '-'.
        'Generator_02'.
        '-'.
        'Generator_05'.
        'Generator_07'.
    }.

    actualMenu := self menuItemLabels.

    self assert: expectedMenu = actualMenu

    "Modified (comment): / 28-12-2014 / 22:35:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_build_menu_two_generators
    | expectedMenu actualMenu navigationState |

    expectedMenu := {
        'Label_01'.
        'Label_02'. 
        'Translated BunchOfGenerators'. 
        {'Translated Generator_01'. 'Translated Generator_03'}.
        'Label_03'.
    }.

    self
        addGenerator: 'Generator_01' group: #();
        addGenerator: 'Generator_02' group: #();
        addGenerator: 'Generator_03' group: #().

    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
    provider last
        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.

    navigationState := Tools::NavigationState new.
    navigationState selectedClasses value: {CustomMenuBuilderTests}.

    builder
        perspective: CustomPerspective classPerspective;
        menu: menu;
        submenuLabel: 'BunchOfGenerators';
        afterMenuItemLabelled: 'Label_02';
        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring label ~= 'Generator_02' ];
        navigationState: navigationState;
        resources: resources;
        buildMenu.    

    actualMenu := self menuItemLabels.

    self assert: expectedMenu = actualMenu.

    (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item | 
        self assert: item enabled value
    ].

    "Created: / 28-12-2014 / 22:48:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
    "Modified: / 04-01-2015 / 15:08:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_build_menu_two_generators_empty_builder

    self
        addGenerator: 'Generator_01' group: #();
        addGenerator: 'Generator_02' group: #();
        addGenerator: 'Generator_03' group: #().

    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
    provider last
        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.

    self should: [
        builder buildMenu
    ] raise: Error suchThat: [ :error |
        (error description) = 'Attributes named menu and perspective are required.'
    ].

    "Created: / 04-01-2015 / 15:31:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_build_menu_two_generators_empty_label
    | expectedMenu actualMenu navigationState |

    expectedMenu := {
        'Label_01'.
        'Label_02'. 
        'Label_03'.
        'Unknown menu label'.
        {'Generator_01'. 'Generator_02'. 'Generator_03'}
    }.

    self
        addGenerator: 'Generator_01' group: #();
        addGenerator: 'Generator_02' group: #();
        addGenerator: 'Generator_03' group: #().

    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
    provider last
        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.

    navigationState := Tools::NavigationState new.
    navigationState selectedClasses value: {CustomMenuBuilderTests}.

    builder
        perspective: CustomPerspective classPerspective;
        menu: menu;
        buildMenu.    

    actualMenu := self menuItemLabels.

    self assert: expectedMenu = actualMenu

    "Created: / 04-01-2015 / 15:44:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_build_menu_two_generators_without_filter
    | expectedMenu actualMenu navigationState |

    expectedMenu := {
        'Label_01'.
        'Label_02'. 
        'Translated BunchOfGenerators'. 
        {'Translated Generator_01'. 'Translated Generator_02'. 'Translated Generator_03'}.
        'Label_03'.
    }.

    self
        addGenerator: 'Generator_01' group: #();
        addGenerator: 'Generator_02' group: #();
        addGenerator: 'Generator_03' group: #().

    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
    provider last
        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.

    navigationState := Tools::NavigationState new.
    navigationState selectedClasses value: {CustomMenuBuilderTests}.

    builder
        perspective: CustomPerspective classPerspective;
        menu: menu;
        submenuLabel: 'BunchOfGenerators';
        afterMenuItemLabelled: 'Label_02';
        navigationState: navigationState;
        resources: resources;
        buildMenu.    

    actualMenu := self menuItemLabels.

    self assert: expectedMenu = actualMenu.

    (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item | 
        self assert: item enabled value
    ].

    "Created: / 29-12-2014 / 09:33:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
    "Modified: / 04-01-2015 / 15:08:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_groups_sort_block
    | expectedGroups actualGroups |

    actualGroups := {
        #(Group_09 Subgroup_02 Subsubgroup_02).
        #(Group_09 Subgroup_01 Subsubgroup_02).
        #(Group_09 Subgroup_01 Subsubgroup_01).
        #(Group_01).
        #(Group_09 Subgroup_01).
        #(Group_01 Subgroup_01).
        #(Group_03).
        #(Group_02 Subgroup_02).
        #(Group_02 Subgroup_01).
        #(Group_10).
        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
        #().
    }.

    "Maybe better order?"
    "
    expectedGroups := {
        #().
        #(Group_01).
        #(Group_01 Subgroup_01).
        #(Group_02 Subgroup_01).
        #(Group_02 Subgroup_02).
        #(Group_03).
        #(Group_09 Subgroup_01).
        #(Group_09 Subgroup_01 Subsubgroup_01).
        #(Group_09 Subgroup_01 Subsubgroup_02).
        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
        #(Group_09 Subgroup_02 Subsubgroup_02).
        #(Group_10)
    }. "

    expectedGroups := {
        #().
        #(Group_01).
        #(Group_03).
        #(Group_10).
        #(Group_01 Subgroup_01).
        #(Group_02 Subgroup_01).
        #(Group_02 Subgroup_02).
        #(Group_09 Subgroup_01).
        #(Group_09 Subgroup_01 Subsubgroup_01).
        #(Group_09 Subgroup_01 Subsubgroup_02).
        #(Group_09 Subgroup_02 Subsubgroup_02).
        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
    }.

    actualGroups sort: builder groupsSortBlock.    
    
    self assert: expectedGroups = actualGroups

    "Modified (format): / 28-12-2014 / 21:54:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_place_menu_item_after_menu_item_labeled_for_menu_item_empty
    | menuItem expectedMenuItemLabels actualMenuItemLabels |

    menuItem := MenuItem label: 'SomeLabel'.

    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.

    builder placeMenuItem: menuItem afterMenuItemLabeled: nil forMenu: menu.

    actualMenuItemLabels := self menuItemLabels.

    self assert: expectedMenuItemLabels = actualMenuItemLabels

    "Created: / 04-01-2015 / 15:41:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_place_menu_item_after_menu_item_labeled_for_menu_item_found
    | menuItem expectedMenuItemLabels actualMenuItemLabels |

    menuItem := MenuItem label: 'SomeLabel'.

    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'SomeLabel'. 'Label_03'}.

    builder placeMenuItem: menuItem afterMenuItemLabeled: 'Label_02' forMenu: menu.

    actualMenuItemLabels := self menuItemLabels.

    self assert: expectedMenuItemLabels = actualMenuItemLabels

    "Modified: / 28-12-2014 / 10:41:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!

test_place_menu_item_after_menu_item_labeled_for_menu_item_not_found
    | menuItem expectedMenuItemLabels actualMenuItemLabels |

    menuItem := MenuItem label: 'SomeLabel'.

    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.

    builder placeMenuItem: menuItem afterMenuItemLabeled: 'NotExistingLabel' forMenu: menu.

    actualMenuItemLabels := self menuItemLabels.

    self assert: expectedMenuItemLabels = actualMenuItemLabels

    "Created: / 28-12-2014 / 10:45:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !

!CustomMenuBuilderTests class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !