package org.javersion.path;

import static org.javersion.path.PropertyPath.NodeId.valueOf;
import static org.javersion.path.PropertyPath.ROOT;
import static org.assertj.core.api.Assertions.*;
import static org.javersion.path.PropertyPath.parse;

import org.javersion.path.PropertyPath.NodeId;
import org.javersion.path.Schema.Builder;
import org.junit.Test;

public class SchemaTest {

    @Test
    public void anything_goes() {
        Builder<String> root = new Builder<>("root");
        root.connect(ROOT.any(), root);
        assertThat(root.getValue()).isEqualTo("root");

        Schema<String> schema = root.build();
        assertThat(schema.getValue()).isEqualTo("root");
        assertThat(schema.getChild(NodeId.ANY)).isEqualTo(schema);
        assertThat(schema.find(ROOT)).isEqualTo(schema);
        assertThat(schema.find(ROOT.key("foo").property("bar").index(123))).isEqualTo(schema);
    }

    @Test
    public void list_of_named_objects() {
        Builder<String> root = new Builder<>("root");
        Builder<String> list = root.addChild(valueOf("list"), new Builder<>());
        list.getOrCreate(parse("[].name"), "name");
        root.getOrCreate(parse("list[]")).setValue("element");

        Schema<String> schema = root.build();
        assertThat(schema.getValue()).isEqualTo("root");
        Schema<String> child = schema.get(parse("list"));
        assertThat(child.getValue()).isNull();
        child = child.getChild(NodeId.ANY_INDEX);
        assertThat(child.getValue()).isEqualTo("element");
        assertThat(child.get(parse("name")).getValue()).isEqualTo("name");
    }

    @Test
    public void has_child() {
        Builder<String> root = new Builder<>("root");
        root.getOrCreate(ROOT.property("property"));
        Schema<String> schema = root.build();

        assertThat(schema.hasChildren()).isTrue();
        assertThat(schema.hasChild(valueOf("property"))).isTrue();
        assertThat(schema.hasChild(NodeId.ANY_KEY)).isFalse();

        schema = schema.getChild(valueOf("property"));
        assertThat(schema.hasChildren()).isFalse();
        assertThat(schema.hasChild(NodeId.ANY)).isFalse();
    }

    @Test(expected = IllegalArgumentException.class)
    public void node_not_found() {
        new Builder<>("root").get(ROOT.property("foo"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void get_by_null_throws_exception() {
        new Builder<>().get(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void builder_get_child_by_null_throws_exception() {
        new Builder<>().getChild(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void schema_get_child_by_null_throws_exception() {
        new Builder<>().build().getChild(null);
    }
}

@@ -379,16 +379,1210 @@
 Test %7B%0A%0A
+    @Test%0A    public void secured_path_besides_anything() %7B%0A        // : %22root%22%0A        // secure.property: %22secure property%22%0A        // *: %22any%22%0A        // **: @*%0A%0A        Builder%3CString%3E root = new Builder%3C%3E(%22root%22);%0A        Builder%3CString%3E any = new Builder%3C%3E(%22any%22);%0A%0A        root.addChild(NodeId.ANY, any);%0A        any.addChild(NodeId.ANY, any);%0A        root.getOrCreate(ROOT.property(%22secure%22).property(%22property%22), %22secure property%22);%0A%0A        Schema%3CString%3E schema = root.build();%0A        assertThat(schema.get(ROOT.property(%22foo%22)).getValue()).isEqualTo(%22any%22);%0A        assertThat(schema.get(ROOT.key(%22foo%22).key(%22bar%22)).getValue()).isEqualTo(%22any%22);%0A        assertThat(schema.get(ROOT.index(123).index(456)).getValue()).isEqualTo(%22any%22);%0A        assertThat(schema.get((ROOT.property(%22foo%22).property(%22secure%22))).getValue()).isEqualTo(%22any%22);%0A%0A        assertThat(schema.get(ROOT.property(%22secure%22).property(%22property%22)).getValue()).isEqualTo(%22secure property%22);%0A%0A        try %7B%0A            schema.get(ROOT.property(%22secure%22).property(%22insecure%22));%0A            fail(%22Found insecure under secure%22);%0A        %7D catch (IllegalArgumentException e) %7B%0A            // as expected%0A        %7D%0A    %7D%0A%0A
     @Tes

Test combining totally free with strict schema