Content of file UserActionProviderContextMenuBuilderTest.java
/*
* *********************************************************************************************************************
*
* SteelBlue: DCI User Interfaces
* http://tidalwave.it/projects/steelblue
*
* Copyright (C) 2015 - 2021 by Tidalwave s.a.s. (http://tidalwave.it)
*
* *********************************************************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* *********************************************************************************************************************
*
* git clone https://bitbucket.org/tidalwave/steelblue-src
* git clone https://github.com/tidalwave-it/steelblue-src
*
* *********************************************************************************************************************
*/
package it.tidalwave.role.ui.javafx.impl;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import it.tidalwave.role.ui.Displayable;
import it.tidalwave.role.ui.javafx.impl.common.DefaultCellBinder;
import it.tidalwave.role.ui.javafx.impl.common.RoleBag;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.MenuItem;
import it.tidalwave.role.ContextManager;
import it.tidalwave.role.spi.DefaultContextManagerProvider;
import it.tidalwave.role.ui.UserAction;
import it.tidalwave.role.ui.UserActionProvider;
import it.tidalwave.role.ui.spi.DefaultUserActionProvider;
import it.tidalwave.util.spi.AsDelegateProvider;
import lombok.experimental.Delegate;
import lombok.RequiredArgsConstructor;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.Mockito.*;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
*
**********************************************************************************************************************/
public class UserActionProviderContextMenuBuilderTest
{
@RequiredArgsConstructor
static class TestExecutorService implements ExecutorService
{
public final List<AssertionError> assertionErrors = new ArrayList<>();
static interface Exclusions
{
public Future<?> submit (Runnable runnable);
}
@Delegate(excludes = Exclusions.class)
private final ExecutorService delegate;
@Override @Nonnull
public Future<?> submit (final Runnable task)
{
return delegate.submit(() ->
{
try
{
task.run();
}
catch (AssertionError e)
{
assertionErrors.add(e);
}
});
}
}
private DefaultCellBinder underTest;
private List<UserAction> actions;
private RoleBag roleMapWithoutUserActionProvider;
private RoleBag roleMapWithUserActionProvider;
private TestExecutorService executorService;
private void checkThread()
{
assertThat("Must not be in the FX thread!", Platform.isFxApplicationThread(), is(false));
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@BeforeMethod
public void setup()
{
AsDelegateProvider.Locator.set(AsDelegateProvider.empty());
ContextManager.Locator.set(new DefaultContextManagerProvider()); // TODO: possibly drop this
possibly drop this
actions = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
actions.add(spy(UserAction.of(this::checkThread, Displayable.of("Action #" + i))));
}
final UserActionProvider userActionProvider = new DefaultUserActionProvider()
{
@Override @Nonnull
public Collection<? extends UserAction> getActions()
{
return actions;
}
};
roleMapWithoutUserActionProvider = new RoleBag();
roleMapWithUserActionProvider = new RoleBag();
roleMapWithUserActionProvider.put(UserActionProvider.class, userActionProvider);
executorService = new TestExecutorService(Executors.newSingleThreadExecutor());
underTest = new DefaultCellBinder(executorService);
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Test
public void must_return_empty_list_when_UserActionProvider_is_not_present()
{
final List<MenuItem> menuItems = underTest.createMenuItems(roleMapWithoutUserActionProvider);
assertThat(menuItems, is(notNullValue()));
assertThat(menuItems.isEmpty(), is(true));
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Test
public void must_set_the_MenuItem_text_from_UserAction_Displayable()
{
final List<MenuItem> menuItems = underTest.createMenuItems(roleMapWithUserActionProvider);
assertThat(menuItems, is(not(nullValue())));
assertThat(menuItems.size(), is(actions.size()));
for (int i = 0; i < menuItems.size(); i++)
{
final MenuItem menuItem = menuItems.get(i);
assertThat(menuItem, is(not(nullValue())));
assertThat(menuItem.getText(), is("Action #" + i));
}
}
/*******************************************************************************************************************
*
******************************************************************************************************************/
@Test
public void must_invoke_callbacks_in_a_non_FX_thread()
throws InterruptedException
{
final List<MenuItem> menuItems = underTest.createMenuItems(roleMapWithUserActionProvider);
assertThat(menuItems, is(not(nullValue())));
assertThat(menuItems.size(), is(actions.size()));
for (final MenuItem menuItem : menuItems)
{
menuItem.getOnAction().handle(new ActionEvent());
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
for (int i = 0; i < menuItems.size(); i++)
{
verify(actions.get(i), times(1)).actionPerformed();
// verifyNoMoreInteractions(actions.get(i));
}
if (!executorService.assertionErrors.isEmpty())
{
throw executorService.assertionErrors.get(0);
}
}
}