/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.jena.sparql.path;
import java.util.ArrayList ;
import java.util.List ;
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.atlas.junit.BaseTest ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
import org.apache.jena.query.ARQ ;
import org.apache.jena.sparql.path.Path ;
import org.apache.jena.sparql.path.PathFactory ;
import org.apache.jena.sparql.path.eval.PathEval ;
import org.apache.jena.sparql.sse.SSE ;
import org.junit.AfterClass ;
import org.junit.BeforeClass ;
import org.junit.Test ;
public class TestPath2 extends BaseTest
{
@BeforeClass static public void beforeClass() {}
@AfterClass static public void afterClass() {}
// SEE format listy of pairs
static String prefix = "http://example/" ;
static String prefixes = "((: <"+prefix+">))" ;
static String gs = StrUtils.strjoinNL(
"(prefix "+prefixes,
" (graph",
// A simple directed loop + a tail
" (:x :p :y)" ,
" (:y :p :z)" ,
" (:z :p :x)" ,
" (:x :p :a)" ,
// Diamond
" (:x :q :y1)" ,
" (:x :q :y2)" ,
" (:y1 :q :z)" ,
" (:y2 :q :z)" ,
// 2 Diamonds :x - :z - :b
" (:x :r :y1)" ,
" (:x :r :y2)" ,
" (:y1 :r :z)" ,
" (:y2 :r :z)" ,
" (:z :r :a1)" ,
" (:z :r :a2)" ,
" (:a1 :r :b)" ,
" (:a2 :r :b)" ,
"))"
) ;
static Node parse(String str) { return SSE.parseNode("<"+prefix+str.substring(1)+">") ; }
static Graph graph = SSE.parseGraph(gs) ;
static Node x = parse(":x") ;
@Test public void path_01() { test(x, "(path :p)", ":a", ":y") ; }
@Test public void path_02() { test(x, "(alt :q :r)", ":y2", ":y1", ":y2", ":y1") ; }
@Test public void path_03() { test(x, "(seq :p :p)", ":z") ; }
@Test public void path_04() { test(x, "(seq :q :q)", ":z", ":z") ; }
@Test public void path_05() { test(x, "(path? :p)", ":x", ":a", ":y") ; }
@Test public void path_06() { test(x, "(path? :X)", ":x") ; }
@Test public void path_07() { test(x, "(notoneof :p)", ":y2", ":y1", ":y2", ":y1") ; }
@Test public void path_08() { test(x, "(notoneof :Z)", ":y2", ":y1", ":y2", ":y1", ":a", ":y") ; }
@Test public void path_09() { test(x, "(notoneof (rev :p))" ) ; }
@Test public void path_10() { test(x, "(notoneof (rev :Z))", ":z") ; }
@Test public void path_11() { test(x, "(notoneof :q (rev :p))", ":y2", ":y1", ":a", ":y") ; }
@Test public void path_12() { test(x, "(notoneof :q (rev :Z))", ":y2", ":y1", ":a", ":y", ":z") ; }
@Test public void path_13() { test(x, "(mod 0 2 :q)", ":x", ":y2", ":z", ":y1", ":z") ; }
@Test public void path_14() { test(x, "(mod 0 1 :q)", ":x", ":y2", ":y1") ; }
@Test public void path_15() { test(x, "(mod 0 1 :r)", ":x", ":y2", ":y1") ; }
@Test public void path_16() { test(x, "(mod 0 3 :r)", ":x", ":y2", ":z", ":a2", ":a1", ":y1", ":z", ":a2", ":a1") ; }
@Test public void path_17() { test(x, "(mod 0 99 :r)", ":x", ":y2", ":z", ":a2", ":b", ":a1", ":b", ":y1", ":z", ":a2", ":b", ":a1", ":b") ; }
@Test public void path_18() { test(x, "(mod 0 2 :q)", ":x", ":y2", ":z", ":y1", ":z") ; }
@Test public void path_19() { test(x, "(pathN 2 :p)", ":z") ; }
@Test public void path_20() { test(x, "(pathN 2 :q)", ":z", ":z") ; }
@Test public void path_21() { test(x, "(distinct(pathN 2 :q))", ":z") ; }
@Test public void path_30() { test(x, "(path* :p)", ":x", ":a", ":y", ":z") ; }
@Test public void path_31() { test(x, "(pathN* :p)", ":x", ":a", ":y", ":z") ; }
@Test public void path_32() { test(x, "(path+ :p)", ":a", ":y", ":z", ":x") ; }
@Test public void path_33() { test(x, "(pathN+ :p)", ":a", ":y", ":z", ":x", ":a") ; }
@Test public void path_34() { test(x, "(path+ :r)", ":y2", ":z", ":a2", ":b", ":a1", ":y1") ; }
@Test public void path_35() { test(x, "(pathN+ :r)", ":y2", ":z", ":a2", ":b", ":a1", ":b", ":y1", ":z", ":a2", ":b", ":a1", ":b") ; }
@Test public void path_36() { test(x, "(path* :r)", ":x", ":y2", ":z", ":a2", ":b", ":a1", ":y1") ; }
@Test public void path_37() { test(x, "(pathN* :r)", ":x", ":y2", ":z", ":a2", ":b", ":a1", ":b", ":y1", ":z", ":a2", ":b", ":a1", ":b") ; }
// static int i = 0 ;
private void test(Node start, String pathStr, String ... results)
{
//System.out.println(pathStr) ;
String ps = "(prefix "+prefixes+" "+pathStr+")" ;
Path path = SSE.parsePath(ps) ;
List<Node> nodes1 = Iter.toList(PathEval.eval(graph, start, PathFactory.pathDistinct(path), ARQ.getContext() )) ;
List<Node> nodes2 = Iter.toList(PathEval.eval(graph, start, path, ARQ.getContext() )) ;
List<Node> expected = new ArrayList<>() ;
for ( String n : results )
expected.add(parse(n)) ;
List<Node> expected1 = Iter.iter(expected).distinct().toList() ;
// Generate the tests!
// i++ ;
// Transform<Node, String> t = new Transform<Node, String> (){
//
// @Override
// public String convert(Node item)
// {
// String x = item.getURI() ;
// x = x.replace("http://example/", ":") ;
// return "\""+x+"\"" ;
// }} ;
//
// String x = Iter.iter(nodes2).map(t).asString(", ") ;
// System.out.printf("@Test public void path_%02d() { test(x, \"%s\", %s) ; } ", i, pathStr, x) ;
// System.out.println() ;
assertSameArray(expected, nodes2) ;
assertSameArray(expected1, nodes1) ;
}
private static void assertSameArray(List<Node> expected, List<Node> actual)
{
assertEquals(expected.size(), actual.size()) ;
List<Node> x = new ArrayList<>(expected) ;
for ( Node n : actual )
{
if ( x.contains(n) )
x.remove(n) ;
}
if ( x.size() != 0 )
fail("Different: Expected: "+expected+", actual: "+actual) ;
}
}