Skip to content

Commit d0f9679

Browse files
authored
Merge pull request functionaljava#349 from gliptak/coverage10
Add Parser tests
2 parents 3ed766a + 22cf4b4 commit d0f9679

File tree

5 files changed

+113
-0
lines changed

5 files changed

+113
-0
lines changed

core/src/main/java/fj/Equal.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import fj.data.vector.V6;
1111
import fj.data.vector.V7;
1212
import fj.data.vector.V8;
13+
import fj.parser.Result;
1314

1415
import java.math.BigDecimal;
1516
import java.math.BigInteger;
@@ -355,6 +356,13 @@ public static <A, B> Equal<Either<A, B>> eitherEqual(final Equal<A> ea, final Eq
355356
));
356357
}
357358

359+
public static <I, A> Equal<Result<I, A>> resultEqual(final Equal<A> ea, final Equal<I> ei) {
360+
Definition<A> eaDef = ea.def;
361+
Definition<I> eiDef= ei.def;
362+
return equalDef((r1, r2) -> eaDef.equal(r1.value(), r2.value()) && eiDef.equal(r1.rest(), r2.rest()));
363+
}
364+
365+
358366
/**
359367
* An equal instance for the {@link Validation} type.
360368
*

core/src/main/java/fj/Hash.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import fj.data.vector.V6;
1111
import fj.data.vector.V7;
1212
import fj.data.vector.V8;
13+
import fj.parser.Result;
1314

1415
import java.math.BigDecimal;
1516
import java.math.BigInteger;
@@ -162,6 +163,25 @@ public static <A, B> Hash<Either<A, B>> eitherHash(final Hash<A> ha, final Hash<
162163
return hash(e -> e.isLeft() ? ha.hash(e.left().value()) : hb.hash(e.right().value()));
163164
}
164165

166+
/**
167+
* A hash instance for the {@link Result} type.
168+
*
169+
* @param ha Hash the <code>Result</code> value.
170+
* @param hi Hash the <code>Result</code> remainder.
171+
* @return A hash instance for the {@link Result} type.
172+
*/
173+
public static <I, A> Hash<Result<I, A>> resultHash(Hash<A> ha, Hash<I> hi) {
174+
return hash(res -> {
175+
final int p = 419;
176+
int r = 239;
177+
178+
r = p * r + ha.hash(res.value());
179+
r = p * r + hi.hash(res.rest());
180+
181+
return r;
182+
});
183+
}
184+
165185
/**
166186
* A hash instance for the {@link Validation} type.
167187
*

core/src/main/java/fj/Show.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import fj.data.vector.V6;
1313
import fj.data.vector.V7;
1414
import fj.data.vector.V8;
15+
import fj.parser.Result;
1516

1617
import java.math.BigDecimal;
1718
import java.math.BigInteger;
@@ -255,6 +256,19 @@ public static <A, B> Show<Either<A, B>> eitherShow(final Show<A> sa, final Show<
255256
fromString("Right(").append(sb.f.f(e.right().value())).append(single(')')));
256257
}
257258

259+
/**
260+
* A show instance for the {@link Result} type.
261+
*
262+
* @param sa Show for the {@link Result} value.
263+
* @param si Show for the {@link Result} remainder.
264+
* @return A show instance for the {@link Result} type.
265+
*/
266+
public static <I, A> Show<Result<I, A>> resultShow(Show<A> sa, Show<I> si) {
267+
return show(res ->
268+
fromString("Result(").append(sa.f.f(res.value()))
269+
.append(single(',')).append(si.f.f(res.rest())).append(single(')')));
270+
}
271+
258272
/**
259273
* A show instance for the {@link Validation} type.
260274
*

core/src/main/java/fj/parser/Result.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package fj.parser;
22

3+
import fj.Equal;
34
import fj.F;
5+
import fj.Hash;
6+
import fj.Show;
47

58
import static fj.Function.curry;
69

@@ -21,6 +24,22 @@ private Result(final I i, final A a) {
2124
this.a = a;
2225
}
2326

27+
@Override
28+
public final int hashCode() {
29+
return Hash.resultHash(Hash.<A>anyHash(), Hash.<I>anyHash()).hash(this);
30+
}
31+
32+
@Override
33+
public final String toString() {
34+
return Show.resultShow(Show.<A>anyShow(), Show.<I>anyShow()).showS(this);
35+
}
36+
37+
@Override
38+
public final boolean equals(Object other) {
39+
return Equal.equals0(Result.class, this, other, () -> Equal.resultEqual(Equal.anyEqual(), Equal.anyEqual()));
40+
}
41+
42+
2443
/**
2544
* The remainder of the parse input.
2645
*
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package fj.parser;
2+
3+
import fj.F;
4+
import fj.F0;
5+
import fj.data.Stream;
6+
import fj.data.Validation;
7+
import org.junit.Test;
8+
9+
import static fj.parser.Result.result;
10+
import static org.hamcrest.core.Is.is;
11+
import static org.junit.Assert.*;
12+
13+
public class ParserTest {
14+
@Test
15+
public void testParserFail() {
16+
final Parser<String, String, Exception> fail = Parser.fail(new ParseException());
17+
assertThat(fail.parse("").fail(), is(new ParseException()));
18+
}
19+
20+
@Test
21+
public void testParserValue() {
22+
final Parser<String, String, Exception> p = Parser.parser(s -> s.isEmpty() ?
23+
Validation.fail(new ParseException()) :
24+
Validation.success(result(s.substring(1), s.substring(0, 1)))
25+
);
26+
final Result<String, String> r = p.parse("abc").success();
27+
assertThat(r.value(), is("a"));
28+
assertThat(r.rest(), is("bc"));
29+
}
30+
31+
@Test
32+
public void testParserBind() {
33+
final Parser<String, String, Exception> p = Parser.value("a");
34+
final Parser<String, String, Exception> fail = Parser.fail(new ParseException());
35+
assertThat(p.bind(o -> fail).parse("aaaa").fail(), is(new ParseException()));
36+
}
37+
38+
@Test
39+
public void testParserStream() {
40+
Stream<Character> s = Stream.fromString("abc");
41+
Result<Stream<Character>, Character> r = Parser.CharsParser.character('a').parse(s).success();
42+
assertThat(r, is(Result.result(Stream.fromString("bc"), 'a')));
43+
}
44+
45+
class ParseException extends Exception {
46+
@Override
47+
public boolean equals (Object obj) {
48+
return (obj instanceof ParseException);
49+
}
50+
}
51+
52+
}

0 commit comments

Comments
 (0)