addFactory method for MarkwonSpansFactory
This commit is contained in:
parent
740ff1013c
commit
7f3f3368be
@ -34,6 +34,15 @@ public interface MarkwonSpansFactory {
|
|||||||
@NonNull
|
@NonNull
|
||||||
<N extends Node> Builder setFactory(@NonNull Class<N> node, @Nullable SpanFactory factory);
|
<N extends Node> Builder setFactory(@NonNull Class<N> node, @Nullable SpanFactory factory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to add a {@link SpanFactory} for a Node. This method will merge existing
|
||||||
|
* {@link SpanFactory} with the specified one.
|
||||||
|
*
|
||||||
|
* @since 3.0.1-SNAPSHOT
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
<N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be useful when <em>enhancing</em> an already defined SpanFactory with another one.
|
* Can be useful when <em>enhancing</em> an already defined SpanFactory with another one.
|
||||||
*/
|
*/
|
||||||
|
@ -5,8 +5,10 @@ import android.support.annotation.Nullable;
|
|||||||
|
|
||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +54,27 @@ class MarkwonSpansFactoryImpl implements MarkwonSpansFactory {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public <N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||||
|
// if there is no factory registered for this node -> just add it
|
||||||
|
final SpanFactory existing = factories.get(node);
|
||||||
|
if (existing == null) {
|
||||||
|
factories.put(node, factory);
|
||||||
|
} else {
|
||||||
|
// existing span factory can be of CompositeSpanFactory at this point -> append to it
|
||||||
|
if (existing instanceof CompositeSpanFactory) {
|
||||||
|
((CompositeSpanFactory) existing).factories.add(factory);
|
||||||
|
} else {
|
||||||
|
// if it's not composite at this point -> make it
|
||||||
|
final CompositeSpanFactory compositeSpanFactory =
|
||||||
|
new CompositeSpanFactory(existing, factory);
|
||||||
|
factories.put(node, compositeSpanFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
|
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
|
||||||
@ -74,4 +97,28 @@ class MarkwonSpansFactoryImpl implements MarkwonSpansFactory {
|
|||||||
return new MarkwonSpansFactoryImpl(Collections.unmodifiableMap(factories));
|
return new MarkwonSpansFactoryImpl(Collections.unmodifiableMap(factories));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class CompositeSpanFactory implements SpanFactory {
|
||||||
|
|
||||||
|
final List<SpanFactory> factories;
|
||||||
|
|
||||||
|
CompositeSpanFactory(@NonNull SpanFactory first, @NonNull SpanFactory second) {
|
||||||
|
this.factories = new ArrayList<>(3);
|
||||||
|
this.factories.add(first);
|
||||||
|
this.factories.add(second);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
// please note that we do not check it factory itself returns an array of spans,
|
||||||
|
// as this behaviour is supported now (previously we supported only a single-level array)
|
||||||
|
final int length = factories.size();
|
||||||
|
final Object[] out = new Object[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
out[i] = factories.get(i).getSpans(configuration, props);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,18 @@ import org.junit.runner.RunWith;
|
|||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(manifest = Config.NONE)
|
@Config(manifest = Config.NONE)
|
||||||
@ -87,4 +92,58 @@ public class MarkwonSpansFactoryImplTest {
|
|||||||
assertNull(factory.get(type));
|
assertNull(factory.get(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composite_span_factory() {
|
||||||
|
// validate that composite span factory returns (calls) all span-factories
|
||||||
|
|
||||||
|
final SpanFactory first = mock(SpanFactory.class);
|
||||||
|
final SpanFactory second = mock(SpanFactory.class);
|
||||||
|
|
||||||
|
final MarkwonSpansFactoryImpl.CompositeSpanFactory factory =
|
||||||
|
new MarkwonSpansFactoryImpl.CompositeSpanFactory(first, second);
|
||||||
|
|
||||||
|
final Object spans = factory.getSpans(mock(MarkwonConfiguration.class), mock(RenderProps.class));
|
||||||
|
assertNotNull(spans);
|
||||||
|
assertTrue(spans.getClass().isArray());
|
||||||
|
assertEquals(2, ((Object[]) spans).length);
|
||||||
|
|
||||||
|
verify(first, times(1)).getSpans(any(MarkwonConfiguration.class), any(RenderProps.class));
|
||||||
|
verify(second, times(1)).getSpans(any(MarkwonConfiguration.class), any(RenderProps.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builder_add_factory() {
|
||||||
|
// here is what we should validate:
|
||||||
|
// * if we call addFactory and there is none already -> supplied factory
|
||||||
|
// * if there is
|
||||||
|
// * * if not composite -> make composite
|
||||||
|
// * * if composite -> add to it
|
||||||
|
|
||||||
|
final MarkwonSpansFactoryImpl.BuilderImpl builder = new MarkwonSpansFactoryImpl.BuilderImpl();
|
||||||
|
|
||||||
|
final SpanFactory first = mock(SpanFactory.class);
|
||||||
|
final SpanFactory second = mock(SpanFactory.class);
|
||||||
|
final SpanFactory third = mock(SpanFactory.class);
|
||||||
|
|
||||||
|
final Class<Node> node = Node.class;
|
||||||
|
|
||||||
|
// assert none yet
|
||||||
|
assertNull(builder.getFactory(node));
|
||||||
|
|
||||||
|
// add first, none yet -> it should be added without modifications
|
||||||
|
builder.addFactory(node, first);
|
||||||
|
assertEquals(first, builder.getFactory(node));
|
||||||
|
|
||||||
|
// add second -> composite factory will be created
|
||||||
|
builder.addFactory(node, second);
|
||||||
|
final MarkwonSpansFactoryImpl.CompositeSpanFactory compositeSpanFactory =
|
||||||
|
(MarkwonSpansFactoryImpl.CompositeSpanFactory) builder.getFactory(node);
|
||||||
|
assertNotNull(compositeSpanFactory);
|
||||||
|
assertEquals(Arrays.asList(first, second), compositeSpanFactory.factories);
|
||||||
|
|
||||||
|
builder.addFactory(node, third);
|
||||||
|
assertEquals(compositeSpanFactory, builder.getFactory(node));
|
||||||
|
assertEquals(Arrays.asList(first, second, third), compositeSpanFactory.factories);
|
||||||
|
}
|
||||||
}
|
}
|
@ -156,6 +156,12 @@ public class CorePluginTest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public <N extends Node> MarkwonSpansFactory.Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
|
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user