Skip to content

Commit

Permalink
Add SelectItem to flow single selector api
Browse files Browse the repository at this point in the history
- This change makes single/multi same on an api level
  where single selector used key/value map and multi
  selector used list of SelectItem's.
- We still keep use of map on a single select but those
  essentially go directly via SelectItem's.
- Backport #946
- Fixes #957
  • Loading branch information
jvalkeal committed Dec 18, 2023
1 parent 7520799 commit 7cf73bc
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 the original author or authors.
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,11 +17,11 @@

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.jline.utils.AttributedString;

Expand All @@ -40,7 +40,7 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
private String name;
private String resultValue;
private ResultMode resultMode;
private Map<String, String> selectItems = new HashMap<>();
private List<SelectItem> selectItems = new ArrayList<>();
private String defaultSelect;
private Comparator<SelectorItem<String>> comparator;
private Function<SingleItemSelectorContext<String, SelectorItem<String>>, List<AttributedString>> renderer;
Expand Down Expand Up @@ -75,13 +75,22 @@ public SingleItemSelectorSpec resultMode(ResultMode resultMode) {

@Override
public SingleItemSelectorSpec selectItem(String name, String item) {
this.selectItems.put(name, item);
selectItems.add(SelectItem.of(name, item));
return this;
}

@Override
public SingleItemSelectorSpec selectItems(Map<String, String> selectItems) {
this.selectItems.putAll(selectItems);
List<SelectItem> items = selectItems.entrySet().stream()
.map(e -> SelectItem.of(e.getKey(), e.getValue()))
.collect(Collectors.toList());
selectItems(items);
return this;
}

@Override
public SingleItemSelectorSpec selectItems(List<SelectItem> selectItems) {
this.selectItems.addAll(selectItems);
return this;
}

Expand Down Expand Up @@ -163,7 +172,7 @@ public ResultMode getResultMode() {
return resultMode;
}

public Map<String, String> getSelectItems() {
public List<SelectItem> getSelectItems() {
return selectItems;
}

Expand Down Expand Up @@ -202,4 +211,4 @@ public boolean isStoreResult() {
public Function<SingleItemSelectorContext<String, SelectorItem<String>>, String> getNext() {
return next;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 the original author or authors.
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -565,9 +565,9 @@ private Stream<OrderedInputOperation> confirmationInputsStream() {

private Stream<OrderedInputOperation> singleItemSelectorsStream() {
return singleInputs.stream().map(input -> {
List<SelectorItem<String>> selectorItems = input.getSelectItems().entrySet().stream()
.map(e -> SelectorItem.of(e.getKey(), e.getValue()))
.collect(Collectors.toList());
List<SelectorItem<String>> selectorItems = input.getSelectItems().stream()
.map(si -> SelectorItem.of(si.name(), si.item()))
.collect(Collectors.toList());

// setup possible item for initial expose
String defaultSelect = input.getDefaultSelect();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 the original author or authors.
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -65,6 +65,7 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
* @param name the name
* @param item the item
* @return a builder
* @see #selectItems(List)
*/
SingleItemSelectorSpec selectItem(String name, String item);

Expand All @@ -73,9 +74,18 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
*
* @param selectItems the select items
* @return a builder
* @see #selectItems(List)
*/
SingleItemSelectorSpec selectItems(Map<String, String> selectItems);

/**
* Adds a list of select items.
*
* @param selectItems the select items
* @return a builder
*/
SingleItemSelectorSpec selectItems(List<SelectItem> selectItems);

/**
* Automatically selects and exposes a given item.
*
Expand Down Expand Up @@ -156,4 +166,4 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
* @return the parent builder
*/
Builder and();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 the original author or authors.
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,7 +28,9 @@

import org.junit.jupiter.api.Test;

import org.springframework.shell.component.flow.ComponentFlow.Builder;
import org.springframework.shell.component.flow.ComponentFlow.ComponentFlowResult;
import org.springframework.test.util.ReflectionTestUtils;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -339,4 +341,34 @@ public void testAutoShowsDefault() throws InterruptedException {
String single1 = inputWizardResult.getContext().get("single1");
assertThat(single1).isEqualTo("value2");
}

@Test
@SuppressWarnings("unchecked")
public void testBuilderSingleTypes() {
List<SelectItem> selectItems1 = Arrays.asList(SelectItem.of("key1", "value1"), SelectItem.of("key2", "value2"));
Map<String, String> selectItems2 = new HashMap<>();
selectItems2.put("key2", "value2");
selectItems2.put("key3", "value3");

Builder builder1 = ComponentFlow.builder()
.withSingleItemSelector("field1")
.selectItems(selectItems1)
.and();
Builder builder2 = ComponentFlow.builder()
.withSingleItemSelector("field2")
.selectItems(selectItems2)
.and();

List<BaseSingleItemSelector> field1 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder1,
"singleItemSelectors");
List<BaseSingleItemSelector> field2 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder2,
"singleItemSelectors");
assertThat(field1).hasSize(1);
assertThat(field2).hasSize(1);

List<SelectItem> selectItems11 = (List<SelectItem>) ReflectionTestUtils.getField(field1.get(0), "selectItems");
List<SelectItem> selectItems21 = (List<SelectItem>) ReflectionTestUtils.getField(field2.get(0), "selectItems");
assertThat(selectItems11).hasSize(2);
assertThat(selectItems21).hasSize(2);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 the original author or authors.
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,9 +33,8 @@ static class FlowSampleComplex {
private ComponentFlow.Builder componentFlowBuilder;

public void runFlow() {
Map<String, String> single1SelectItems = new HashMap<>();
single1SelectItems.put("key1", "value1");
single1SelectItems.put("key2", "value2");
List<SelectItem> single1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
SelectItem.of("key2", "value2"));
List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
ComponentFlow flow = componentFlowBuilder.clone().reset()
Expand Down

0 comments on commit 7cf73bc

Please sign in to comment.