Improve test suite
diff --git a/t/corpus/field.t b/t/corpus/field.t
index faa45b7..a1ac0dd 100644
--- a/t/corpus/field.t
+++ b/t/corpus/field.t
@@ -1,24 +1,15 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-use Data::Dumper;
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral::Corpus::Builder');
 use_ok('Krawfish::Index');
 
 my $index = Krawfish::Index->new;
-ok(defined $index->add(cat_t('data', 'doc2.jsonld')), 'Add new document');
-ok(defined $index->add(cat_t('data', 'doc1.jsonld')), 'Add new document');
-ok(defined $index->add(cat_t('data', 'doc3-segments.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc2.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc1.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc3-segments.jsonld')), 'Add new document');
 
 ok(my $cb = Krawfish::Koral::Corpus::Builder->new, 'Create CorpusBuilder');
 
diff --git a/t/corpus/or.t b/t/corpus/or.t
index 3774cc0..87e4043 100644
--- a/t/corpus/or.t
+++ b/t/corpus/or.t
@@ -1,24 +1,15 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-use Data::Dumper;
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral::Corpus::Builder');
 use_ok('Krawfish::Index');
 
 my $index = Krawfish::Index->new;
-ok(defined $index->add(simple_doc({id => 2} => qw/aa bb/)), 'Add complex document');
-ok(defined $index->add(simple_doc({id => 3} => qw/aa bb/)), 'Add complex document');
-ok(defined $index->add(simple_doc({id => 5} => qw/aa bb/)), 'Add complex document');
+ok_index($index, {id => 2} => [qw/aa bb/], 'Add complex document');
+ok_index($index, {id => 3} => [qw/aa bb/], 'Add complex document');
+ok_index($index, {id => 5} => [qw/aa bb/], 'Add complex document');
 
 ok(my $cb = Krawfish::Koral::Corpus::Builder->new, 'Create CorpusBuilder');
 
diff --git a/t/index/create_docs.t b/t/index/create_docs.t
index 456215e..f0268cf 100644
--- a/t/index/create_docs.t
+++ b/t/index/create_docs.t
@@ -1,13 +1,9 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
 
-require '' . catfile(dirname(__FILE__), '..', 'util', 'CreateDoc.pm');
-
-my $doc = simple_doc(qw/aa bb aa bb/);
+my $doc = test_doc([qw/aa bb aa bb/]);
 
 ok(exists $doc->{document}, 'Doc exists');
 ok(exists $doc->{document}->{annotations}, 'Annotations exists');
@@ -17,7 +13,7 @@
 is($anno->[-1]->{'@type'}, 'koral:token', '@type is valid');
 is($anno->[-1]->{'wrap'}->{'key'}, 'bb', '@type is valid');
 
-$doc = complex_doc('<1:xy>[aa]<2:opennlp=z>[bb]</1>[corenlp/c=cc|dd]</2>');
+$doc = test_doc('<1:xy>[aa]<2:opennlp=z>[bb]</1>[corenlp/c=cc|dd]</2>');
 
 ok(exists $doc->{document}, 'Doc exists');
 
@@ -50,7 +46,7 @@
 is($token_group->[1]->{'@type'}, 'koral:term', 'Annotation type');
 is($token_group->[1]->{key}, 'dd', 'Annotation key');
 
-$doc = complex_doc('<1:aa><2:aa>[bb]</2>[bb]</1>');
+$doc = test_doc('<1:aa><2:aa>[bb]</2>[bb]</1>');
 $anno = $doc->{document}->{annotations};
 is($anno->[0]->{'@type'}, 'koral:span', 'Span');
 is($anno->[0]->{segments}->[0], 0, 'Span');
@@ -62,7 +58,7 @@
 
 
 # Docs with meta
-$doc = simple_doc({id => 5, author => 'Johann Wolfgang von Goethe'} => qw/aa bb aa bb/);
+$doc = test_doc({id => 5, author => 'Johann Wolfgang von Goethe'} => qw/aa bb aa bb/);
 my $fields = $doc->{document}->{fields};
 is_deeply($fields->[0], {
   '@type' => 'koral:field',
diff --git a/t/plan/exclusion.t b/t/plan/exclusion.t
index 46a96d6..064d53d 100644
--- a/t/plan/exclusion.t
+++ b/t/plan/exclusion.t
@@ -1,25 +1,16 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
 
 use_ok('Krawfish::Koral');
 use_ok('Krawfish::Index');
 
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-
 my $index = Krawfish::Index->new;
 my $koral = Krawfish::Koral->new;
 my $qb = $koral->query_builder;
 
-ok(defined $index->add(complex_doc('<1:aa>[aa]</1>[bb][aa][bb]')), 'Add new document');
+ok_index($index, '<1:aa>[aa]</1>[bb][aa][bb]', 'Add new document');
 
 # Exclusion planning
 
diff --git a/t/plan/position.t b/t/plan/position.t
index 8d173be..fc36efe 100644
--- a/t/plan/position.t
+++ b/t/plan/position.t
@@ -1,24 +1,14 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral');
 use_ok('Krawfish::Index');
 
 my $index = Krawfish::Index->new;
 
-# ok(defined $index->add('t/data/doc3-segments.jsonld'), 'Add new document');
-ok(defined $index->add(complex_doc('<1:opennlp/c=NP>[Der][hey]</1>')), 'Add new document');
+ok_index($index, '<1:opennlp/c=NP>[Der][hey]</1>', 'Add new document');
 
 my $koral = Krawfish::Koral->new;
 
diff --git a/t/plan/repetition.t b/t/plan/repetition.t
index 6e2645a..13e1d76 100644
--- a/t/plan/repetition.t
+++ b/t/plan/repetition.t
@@ -1,23 +1,14 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral');
 use_ok('Krawfish::Index');
 
 my $index = Krawfish::Index->new;
 
-ok(defined $index->add(complex_doc('<1:aaa>[hey][hey]</1>')), 'Add new document');
+ok_index($index, '<1:aaa>[hey][hey]</1>', 'Add new document');
 
 my $koral = Krawfish::Koral->new;
 
diff --git a/t/plan/term_group.t b/t/plan/term_group.t
index e7a7e4c..bee6a71 100644
--- a/t/plan/term_group.t
+++ b/t/plan/term_group.t
@@ -1,9 +1,7 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
 
 
 use_ok('Krawfish::Koral');
@@ -14,13 +12,10 @@
   return catfile(dirname(__FILE__), '..', @_);
 };
 
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
-
 
 my $index = Krawfish::Index->new;
 
-ok(defined $index->add(simple_doc(qw/first second third fourth fifth sixth/)), 'Add new document');
+ok_index($index, [qw/first second third fourth fifth sixth/], 'Add new document');
 
 my $koral = Krawfish::Koral->new;
 
diff --git a/t/plan/term_re.t b/t/plan/term_re.t
index 39be638..abb017e 100644
--- a/t/plan/term_re.t
+++ b/t/plan/term_re.t
@@ -1,21 +1,12 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
 my $index = Krawfish::Index->new;
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Add new_document');
 
 ok(my $re = $qb->term_re('Der.*'), 'Regex');
@@ -28,7 +19,7 @@
 ok($re->is_regex, 'Term is regex');
 is($re->match, '~', 'Match operator');
 
-ok(defined $index->add(complex_doc('[a/b=CDE|a/c=FGH][a/l=PART|a/l=BAU|a/l=PUM][b/c=DAU][e/f=UM]')), 'Add doc');
+ok_index($index,'[a/b=CDE|a/c=FGH][a/l=PART|a/l=BAU|a/l=PUM][b/c=DAU][e/f=UM]', 'Add doc');
 
 ok(my $plan = $re->plan_for($index), 'Plan Regex');
 is($plan->to_string, "or('a/l=PART','a/l=PUM')", 'Stringification');
diff --git a/t/query/class.t b/t/query/class.t
index 4ecf3de..c4dc0cb 100644
--- a/t/query/class.t
+++ b/t/query/class.t
@@ -1,22 +1,13 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
 my $index = Krawfish::Index->new;
-ok(defined $index->add(simple_doc(qw/aa bb aa bb/)), 'Add new document');
+ok_index($index, [qw/aa bb aa bb/], 'Add new document');
 
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok(my $wrap = $qb->class($qb->token('bb'), 2), 'Class');
diff --git a/t/query/constraints.t b/t/query/constraints.t
index 64a0924..cb3c4a9 100644
--- a/t/query/constraints.t
+++ b/t/query/constraints.t
@@ -1,23 +1,16 @@
 use strict;
 use warnings;
+use Test::Krawfish;
 use Test::More;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
 
 use Krawfish::Query::Constraint::Position;
 
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
 my $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb|bb]', 'Add complex document');
 
 my $qb = Krawfish::Koral::Query::Builder->new;
 
@@ -30,10 +23,10 @@
 is($wrap->to_string, "constr(pos=precedesDirectly:[aa],[bb])", 'Query is valid');
 ok(my $query = $wrap->plan_for($index), 'Planning');
 is($query->to_string, "constr(pos=2:'aa','bb')", 'Query is valid');
-test_matches($query, qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/);
+matches($query, [qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/]);
 
 $index = Krawfish::Index->new;
-ok(defined $index->add(simple_doc(qw/aa bb aa bb aa bb/)), 'Add complex document');
+ok_index($index, [qw/aa bb aa bb aa bb/], 'Add complex document');
 
 # This equals to [aa]{5:[]+}[bb]
 $wrap = $qb->constraints(
@@ -46,7 +39,7 @@
 ok($query = $wrap->plan_for($index), 'Planning');
 is($query->to_string, "constr(pos=1,class=5:'aa','bb')", 'Query is valid');
 
-test_matches($query, '[0:0-4$0,5,1,2]','[0:0-6$0,5,1,4]','[0:2-6$0,5,3,4]');
+matches($query, ['[0:0-4$0,5,1,2]','[0:0-6$0,5,1,4]','[0:2-6$0,5,3,4]']);
 
 # This equals to [aa]{5:[]*}[bb]
 $wrap = $qb->constraints(
@@ -59,14 +52,15 @@
 ok($query = $wrap->plan_for($index), 'Planning');
 is($query->to_string, "constr(pos=3,class=5:'aa','bb')", 'Query is valid');
 
-test_matches(
-  $query,
-  '[0:0-2]',
-  '[0:0-4$0,5,1,2]',
-  '[0:0-6$0,5,1,4]',
-  '[0:2-4]',
-  '[0:2-6$0,5,3,4]',
-  '[0:4-6]',
+matches(
+  $query, [
+    '[0:0-2]',
+    '[0:0-4$0,5,1,2]',
+    '[0:0-6$0,5,1,4]',
+    '[0:2-4]',
+    '[0:2-6$0,5,3,4]',
+    '[0:4-6]'
+  ]
 );
 
 done_testing;
diff --git a/t/query/exclusion.t b/t/query/exclusion.t
index 2114ee2..5e2084c 100644
--- a/t/query/exclusion.t
+++ b/t/query/exclusion.t
@@ -1,16 +1,7 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-use Data::Dumper;
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral::Query::Builder');
 use_ok('Krawfish::Index');
@@ -20,7 +11,7 @@
 
 # Exclusion planning
 
-ok(defined $index->add(complex_doc('<1:aa>[bb][bb]</1><2:aa>[cc]</2>')), 'Add complex document');
+ok_index($index, '<1:aa>[bb][bb]</1><2:aa>[cc]</2>', 'Add complex document');
 
 my $query = $qb->exclusion(
   [qw/isAround startsWith endsWith matches/],
diff --git a/t/query/next.t b/t/query/next.t
index 15c9129..0da6732 100644
--- a/t/query/next.t
+++ b/t/query/next.t
@@ -1,16 +1,7 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
@@ -18,9 +9,9 @@
 my $index = Krawfish::Index->new;
 
 # Der alte Mann ging über die Straße. Er trug einen lustigen Hut
-ok(defined $index->add(cat_t('data','doc1.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc1.jsonld')), 'Add new document');
 # Der Hut stand dem jungen Mann sehr gut. Er betrachtete sich gern im Spiegel.
-ok(defined $index->add(cat_t('data','doc2.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc2.jsonld')), 'Add new document');
 
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 
@@ -31,7 +22,7 @@
 is($seq->current->to_string, '[1:6-8]', 'Match');
 ok(!$seq->next, 'No more');
 
-ok(defined $index->add(simple_doc(qw/aa bb aa bb/)), 'Add new document');
+ok_index($index, [qw/aa bb aa bb/], 'Add new document');
 
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
@@ -45,81 +36,81 @@
 
 # Reset index - situation [aa]..[bb] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][cc][aa][bb]')), 'Add complex document');
+ok_index($index, '[aa][cc][aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:2-4]/);
+matches($seq, [qw/[0:2-4]/]);
 
 # Reset index - situation [bb][aa] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[bb][aa][bb][aa]')), 'Add complex document');
+ok_index($index, '[bb][aa][bb][aa]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:1-3]/);
+matches($seq, [qw/[0:1-3]/]);
 
 
 # Reset index - situation [aa]..[bb] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][cc][aa][bb]')), 'Add complex document');
+ok_index($index, '[aa][cc][aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:2-4]/);
+matches($seq, [qw/[0:2-4]/]);
 
 # Reset index - situation [bb]..[aa] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[bb][cc][aa][bb]')), 'Add complex document');
+ok_index($index, '[bb][cc][aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:2-4]/);
+matches($seq, [qw/[0:2-4]/]);
 
 
 # Multiple matches
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/]);
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
 # query language: [aa][bb]
-test_matches($seq, qw/[0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2]/]);
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2]/]);
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb|bb][aa|aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb|bb][aa|aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->token('aa'), $qb->token('bb')), 'Seq');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2] [0:2-4] [0:2-4] [0:2-4] [0:2-4]/);
+matches($seq, [qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2] [0:2-4] [0:2-4] [0:2-4] [0:2-4]/]);
 
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('<1:aa><2:aa>[bb]</2>[bb]</1>')), 'Add complex document');
+ok_index($index, '<1:aa><2:aa>[bb]</2>[bb]</1>', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create QueryBuilder');
 ok($wrap = $qb->seq($qb->span('aa'), $qb->token('bb')), 'Seq');
 is($wrap->to_string, '<aa>[bb]', 'Stringification');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2]/);
+matches($seq, [qw/[0:0-2]/]);
 
 
 
diff --git a/t/query/position.t b/t/query/position.t
index c0550e8..ff943ad 100644
--- a/t/query/position.t
+++ b/t/query/position.t
@@ -1,16 +1,7 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
@@ -18,9 +9,9 @@
 my $index = Krawfish::Index->new;
 
 # Der alte Mann ging über die Straße. Er trug einen lustigen Hut
-ok(defined $index->add(cat_t('data', 'doc1.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc1.jsonld')), 'Add new document');
 # Der Hut stand dem jungen Mann sehr gut. Er betrachtete sich gern im Spiegel.
-ok(defined $index->add(cat_t('data', 'doc2.jsonld')), 'Add new document');
+ok(defined $index->add(test_file('doc2.jsonld')), 'Add new document');
 
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 
@@ -36,7 +27,7 @@
 is($seq->current->to_string, '[1:6-8]', 'Match');
 ok(!$seq->next, 'No more');
 
-ok(defined $index->add(simple_doc(qw/aa bb aa bb/)), 'Add new document');
+ok_index($index, [qw/aa bb aa bb/], 'Add new document');
 
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
@@ -49,77 +40,77 @@
 
 # Reset index - situation [aa]..[bb] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][cc][aa][bb]')), 'Add complex document');
+ok_index($index, '[aa][cc][aa][bb]', 'Add complex document');
 
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
+matches($seq, [qw/[0:2-4]/]);
 
-test_matches($seq, qw/[0:2-4]/);
 
 
 # Reset index - situation [bb][aa] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[bb][aa][bb][aa]')), 'Add complex document');
+ok_index($index, '[bb][aa][bb][aa]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:1-3]/);
+matches($seq, [qw/[0:1-3]/]);
 
 # Reset index - situation [aa]..[bb] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][cc][aa][bb]')), 'Add complex document');
+ok_index($index,'[aa][cc][aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'],$qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:2-4]/);
+matches($seq, [qw/[0:2-4]/]);
 
 
 # Reset index - situation [bb]..[aa] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[bb][cc][aa][bb]')), 'Add complex document');
+ok_index($index,'[bb][cc][aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new($index), 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:2-4]/);
+matches($seq, [qw/[0:2-4]/]);
 
 
 # Multiple matches
 # Reset index - situation [bb]..[aa] -> [aa][bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb|bb]')), 'Add complex document');
+ok_index($index,'[aa|aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2]/]);
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
 # query language: [aa][bb]
-test_matches($seq, qw/[0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2]/]);
 
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new($index), 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2]/);
+matches($seq, [qw/[0:0-2] [0:0-2]/]);
 
 
 # Reset index
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|aa][bb|bb][aa|aa][bb|bb]')), 'Add complex document');
+ok_index($index, '[aa|aa][bb|bb][aa|aa][bb|bb]', 'Add complex document');
 ok($qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 ok($wrap = $qb->position(['precedesDirectly'], $qb->token('aa'), $qb->token('bb')), 'Sequence');
 ok($seq = $wrap->plan_for($index), 'Rewrite');
-test_matches($seq, qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2] [0:2-4] [0:2-4] [0:2-4] [0:2-4]/);
+matches($seq, [qw/[0:0-2] [0:0-2] [0:0-2] [0:0-2] [0:2-4] [0:2-4] [0:2-4] [0:2-4]/]);
 
 diag 'Test further';
 
diff --git a/t/query/position_overlap.t b/t/query/position_overlap.t
index 076c738..00b89f0 100644
--- a/t/query/position_overlap.t
+++ b/t/query/position_overlap.t
@@ -1,23 +1,14 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
 my $index = Krawfish::Index->new;
 
-ok(defined $index->add(complex_doc('[aa|bb][aa|bb][aa|bb][aa|bb]')), 'Add new document');
+ok_index($index, '[aa|bb][aa|bb][aa|bb][aa|bb]', 'Add new document');
 
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 
diff --git a/t/query/repetition.t b/t/query/repetition.t
index de00cc5..7160c1f 100644
--- a/t/query/repetition.t
+++ b/t/query/repetition.t
@@ -1,23 +1,15 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
 use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
 my $index = Krawfish::Index->new;
 
-ok(defined $index->add(simple_doc(qw/aa bb bb bb bb cc/)), 'Add new document');
+ok_index($index, [qw/aa bb bb bb bb cc/], 'Add new document');
 
 my $qb = Krawfish::Koral::Query::Builder->new;
 
@@ -32,64 +24,64 @@
 # aa bb [bb bb] bb cc
 # aa bb [bb bb bb] cc
 # aa bb bb [bb bb] cc
-test_matches($rep, qw/[0:1-3]
-                      [0:1-4]
-                      [0:2-4]
-                      [0:2-5]
-                      [0:3-5]/);
+matches($rep, [qw/[0:1-3]
+                  [0:1-4]
+                  [0:2-4]
+                  [0:2-5]
+                  [0:3-5]/]);
 
 
 # Next test
 $index = Krawfish::Index->new;
-ok(defined $index->add(simple_doc(qw/aa bb bb bb cc/)), 'Add new document');
-ok(defined $index->add(simple_doc(qw/bb bb bb bb cc/)), 'Add new document');
+ok_index($index, [qw/aa bb bb bb cc/], 'Add new document');
+ok_index($index, [qw/bb bb bb bb cc/], 'Add new document');
 
 ok($wrap = $qb->repeat( $qb->token('bb'), 1, 3), 'Repeat');
 is($wrap->to_string, '[bb]{1,3}', 'Stringification');
 ok($rep = $wrap->plan_for($index), 'Rewrite');
 is($rep->to_string, "rep(1-3:'bb')", 'Stringification');
 
-test_matches($rep, qw/[0:1-2]
-                      [0:1-3]
-                      [0:1-4]
-                      [0:2-3]
-                      [0:2-4]
-                      [0:3-4]
-                      [1:0-1]
-                      [1:0-2]
-                      [1:0-3]
-                      [1:1-2]
-                      [1:1-3]
-                      [1:1-4]
-                      [1:2-3]
-                      [1:2-4]
-                      [1:3-4]/);
+matches($rep, [qw/[0:1-2]
+                  [0:1-3]
+                  [0:1-4]
+                  [0:2-3]
+                  [0:2-4]
+                  [0:3-4]
+                  [1:0-1]
+                  [1:0-2]
+                  [1:0-3]
+                  [1:1-2]
+                  [1:1-3]
+                  [1:1-4]
+                  [1:2-3]
+                  [1:2-4]
+                  [1:3-4]/]);
 
 # Next test
 $index = Krawfish::Index->new;
-ok(defined $index->add(simple_doc(qw/bb bb bb cc bb bb bb bb dd bb/)), 'Add new document');
+ok_index($index, [qw/bb bb bb cc bb bb bb bb dd bb/], 'Add new document');
 
 ok($wrap = $qb->repeat( $qb->token('bb'), 1, 3), 'Repeat');
 is($wrap->to_string, '[bb]{1,3}', 'Stringification');
 ok($rep = $wrap->plan_for($index), 'Rewrite');
 is($rep->to_string, "rep(1-3:'bb')", 'Stringification');
 
-test_matches($rep, qw/[0:0-1]
-                      [0:0-2]
-                      [0:0-3]
-                      [0:1-2]
-                      [0:1-3]
-                      [0:2-3]
-                      [0:4-5]
-                      [0:4-6]
-                      [0:4-7]
-                      [0:5-6]
-                      [0:5-7]
-                      [0:5-8]
-                      [0:6-7]
-                      [0:6-8]
-                      [0:7-8]
-                      [0:9-10]/);
+matches($rep, [qw/[0:0-1]
+                  [0:0-2]
+                  [0:0-3]
+                  [0:1-2]
+                  [0:1-3]
+                  [0:2-3]
+                  [0:4-5]
+                  [0:4-6]
+                  [0:4-7]
+                  [0:5-6]
+                  [0:5-7]
+                  [0:5-8]
+                  [0:6-7]
+                  [0:6-8]
+                  [0:7-8]
+                  [0:9-10]/]);
 
 
 done_testing;
diff --git a/t/query/term_group.t b/t/query/term_group.t
index ba403c2..eacf21f 100644
--- a/t/query/term_group.t
+++ b/t/query/term_group.t
@@ -1,16 +1,7 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
-use Data::Dumper;
-
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
 
 use_ok('Krawfish::Koral::Query::Builder');
 use_ok('Krawfish::Index');
@@ -19,7 +10,7 @@
 
 # [aa&!bb]
 my $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|bb][aa|bb|cc][aa][bb|cc]')), 'Add complex document');
+ok_index($index, '[aa|bb][aa|bb|cc][aa][bb|cc]', 'Add complex document');
 my $token = $qb->token(
   $qb->term_and('aa', $qb->term_neg('bb'))
 );
@@ -27,11 +18,11 @@
 ok(my $plan = $token->plan_for($index), 'Planning');
 is($plan->to_string, "excl(32:'aa','bb')", 'Stringification');
 
-test_matches($plan, '[0:2-3]');
+matches($plan, ['[0:2-3]']);
 
 # [aa&!bb]
 $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|bb][aa|bb|cc][aa][bb|cc]')), 'Add complex document');
+ok_index($index, '[aa|bb][aa|bb|cc][aa][bb|cc]', 'Add complex document');
 $token = $qb->token(
   $qb->term_or(
     $qb->term_and('aa', $qb->term_neg('bb')),
@@ -41,7 +32,7 @@
 is($token->to_string, '[(aa&!bb)|(bb&cc)]', 'Stringification');
 ok($plan = $token->plan_for($index), 'Planning');
 is($plan->to_string, "or(excl(32:'aa','bb'),pos(32:'bb','cc'))", 'Stringification');
-test_matches($plan, '[0:1-2]', '[0:2-3]','[0:3-4]');
+matches($plan, ['[0:1-2]', '[0:2-3]','[0:3-4]']);
 
 
 
diff --git a/t/query/unique.t b/t/query/unique.t
index 3311257..d33f967 100644
--- a/t/query/unique.t
+++ b/t/query/unique.t
@@ -1,23 +1,14 @@
 use Test::More;
+use Test::Krawfish;
 use strict;
 use warnings;
-use Data::Dumper;
-use File::Basename 'dirname';
-use File::Spec::Functions 'catfile';
 
 use_ok('Krawfish::Index');
 use_ok('Krawfish::Koral::Query::Builder');
 
-sub cat_t {
-  return catfile(dirname(__FILE__), '..', @_);
-};
-
-require '' . cat_t('util', 'CreateDoc.pm');
-require '' . cat_t('util', 'TestMatches.pm');
-
 ok(my $qb = Krawfish::Koral::Query::Builder->new, 'Create Koral::Builder');
 my $index = Krawfish::Index->new;
-ok(defined $index->add(complex_doc('[aa|bb][aa|bb][aa|bb]')), 'Add new document');
+ok_index($index, '[aa|bb][aa|bb][aa|bb]', 'Add new document');
 
 my $query = $qb->token(
   $qb->term_or('aa', 'bb')
@@ -26,12 +17,12 @@
 ok(my $non_unique = $query->plan_for($index), 'TermGroup');
 is($non_unique->to_string, "or('aa','bb')", 'termGroup');
 
-test_matches($non_unique, qw/[0:0-1]
-                             [0:0-1]
-                             [0:1-2]
-                             [0:1-2]
-                             [0:2-3]
-                             [0:2-3]/);
+matches($non_unique, [qw/[0:0-1]
+                         [0:0-1]
+                         [0:1-2]
+                         [0:1-2]
+                         [0:2-3]
+                         [0:2-3]/]);
 
 
 $query = $qb->unique(
@@ -43,9 +34,9 @@
 ok(my $unique = $query->plan_for($index), 'TermGroup');
 is($unique->to_string, "unique(or('aa','bb'))", 'termGroup');
 
-test_matches($unique, qw/[0:0-1]
-                         [0:1-2]
-                         [0:2-3]/);
+matches($unique, [qw/[0:0-1]
+                     [0:1-2]
+                     [0:2-3]/]);
 
 
 
diff --git a/t/util/CreateDoc.pm b/t/util/CreateDoc.pm
deleted file mode 100644
index 75ce639..0000000
--- a/t/util/CreateDoc.pm
+++ /dev/null
@@ -1,203 +0,0 @@
-use strict;
-use warnings;
-
-# Convert: qw/aa bb aa bb/
-sub simple_doc {
-  my $fields;
-  if (ref $_[0] eq 'HASH') {
-    $fields = _fields(shift);
-  };
-
-  my @list = @_;
-
-  my @tokens;
-  foreach (@_) {
-    push @tokens, _token(_key($_))
-  };
-
-  my $doc = {
-    document => {
-      annotations => \@tokens
-    }
-  };
-
-  # Add metadata fields
-  $doc->{document}->{fields} = $fields if $fields;
-  return $doc;
-};
-
-
-# Convert:   '[aa][bb][aa][bb]'
-#            '[aa|bb][bb][aa|bb][bb]'
-#            '<1:xy>[aa]<2:z>[bb]</1>[cc]</2>'
-sub complex_doc {
-  my $string = shift;
-
-  my @segments;
-  my @tokens;
-  my %spans;
-  my $segment = 0;
-
-  while ($string =~ /\G\s*(<[^>]+?>|\[[^\]]+?\])/g) {
-    my $token = $1;
-
-    # Found a token description
-    if ($token =~ /^\[((?:[^\]\|]+?)\s*(?:\|\s*(?:[^\]\|]+?))*)\]$/) {
-      my @group = map { _key($_) } split(/\s*\|\s*/, $1);
-
-      # This is a token group
-      if (@group > 1) {
-
-        # Push group to token list
-        push @tokens, _token(\@group, $segment);
-      }
-
-      # Only a single token available
-      else {
-        # Push token to token list
-        push @tokens, _token($group[0], $segment);
-      };
-
-      $segment++;
-    }
-
-    # Found a span opening
-    elsif ($token =~ /^<(\d)+:([^>]+?)>$/) {
-      my $span = _span($2, $segment);
-
-      # Remember span to modify
-      $spans{$1} = $span;
-      push @tokens, $span;
-    }
-
-    # Found a span closing
-    elsif ($token =~ /^<\/(\d+?)>$/) {
-      if (exists $spans{$1}) {
-        my $seg = $segment -1;
-        if ($seg != $spans{$1}->{segments}->[0]) {
-          push @{$spans{$1}->{segments}}, $segment -1;
-        };
-      }
-      else {
-        warn "Span $1 unknown\n";
-      };
-    };
-  };
-
-  @tokens = sort _token_sort @tokens;
-
-  return {
-    document => {
-      annotations => \@tokens
-    }
-  };
-};
-
-# Return token object
-sub _token {
-  my $tokens = shift;
-  my $hash = {
-    '@type' => 'koral:token'
-  };
-  if (defined $_[0]) {
-    $hash->{'segments'} = [@_];
-  };
-
-  if (ref $tokens eq 'ARRAY') {
-    $hash->{wrap} = {
-      '@type' => 'koral:termGroup',
-      'operands' => $tokens
-    }
-  }
-  else {
-    $hash->{wrap} = $tokens
-  };
-  return $hash;
-};
-
-sub _fields {
-  my $hash = shift;
-  my @fields = ();
-  foreach my $key (sort keys %$hash) {
-    my $type = 'string';
-    if ($key =~ s/^([string])_//) {
-      $type = $1;
-    };
-
-    push(@fields, {
-      '@type' => 'koral:field',
-      'key' => $key,
-      'value' => $hash->{$key},
-      'type' => 'type:' . $type
-    });
-  };
-  \@fields;
-};
-
-# return tokenGroup object
-#sub _token_group {
-#  my $hash = {
-#    '@type' => 'koral:token',
-#    'wrap' => {
-#      '@type' => 'koral:termGroup',
-#      'operands' => shift
-#    }
-#  };
-#  if (defined $_[0]) {
-#    $hash->{'segments'} = [@_];
-#  };
-#  return $hash;
-#};
-
-sub _token_sort {
-  return 0 unless $a->{segments} && $b->{segments};
-  my $seg_a = $a->{segments};
-  my $seg_b = $b->{segments};
-  if ($seg_a->[0] < $seg_b->[0]) {
-    return -1;
-  }
-  elsif ($seg_a->[0] > $seg_b->[0]) {
-    return 1;
-  }
-  elsif ($seg_a->[-1] < $seg_b->[-1]) {
-    return -1;
-  }
-  elsif ($seg_a->[-1] > $seg_b->[-1]) {
-    return 1;
-  };
-  return 0;
-};
-
-
-# Return span object
-sub _span {
-  my $key = {
-    '@type' => 'koral:span',
-    'wrap' => _key(shift)
-  };
-  $key->{'segments'} = [shift];
-  return $key;
-};
-
-
-# Analyze key elements (foundry, layer, key)
-sub _key {
-  my $key = shift;
-  my $hash = {
-    '@type' => 'koral:term'
-  };
-  if ($key =~ m!^([^\/]+?)(?:/([^=]))?=(.+)$!) {
-    $hash->{key} = $3;
-    $hash->{foundry} = $1;
-
-    if ($2) {
-      $hash->{layer} = $2;
-    };
-  }
-  else {
-    $hash->{key} = $key
-  }
-  return $hash;
-};
-
-1;
diff --git a/t/util/TestMatches.pm b/t/util/TestMatches.pm
deleted file mode 100644
index 8c017a8..0000000
--- a/t/util/TestMatches.pm
+++ /dev/null
@@ -1,16 +0,0 @@
-use Test::More;
-
-sub test_matches {
-  my $query = shift;
-  my @matches = @_;
-
-  # Iterate over matches
-  foreach (@_) {
-    ok($query->next, 'Next for ' . $_);
-    is($query->current->to_string, $_, 'Match for '.$_);
-  };
-
-  ok(!$query->next, 'No more matches');
-};
-
-1;