1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.navigation.safe.args.generator
18
19import androidx.navigation.safe.args.generator.NavType.BOOLEAN
20import androidx.navigation.safe.args.generator.NavType.FLOAT
21import androidx.navigation.safe.args.generator.NavType.INT
22import androidx.navigation.safe.args.generator.NavType.REFERENCE
23import androidx.navigation.safe.args.generator.NavType.STRING
24import androidx.navigation.safe.args.generator.models.Action
25import androidx.navigation.safe.args.generator.models.Argument
26import androidx.navigation.safe.args.generator.models.Destination
27import androidx.navigation.safe.args.generator.models.ResReference
28import com.squareup.javapoet.ClassName
29import org.hamcrest.CoreMatchers.`is`
30import org.hamcrest.CoreMatchers.nullValue
31import org.hamcrest.MatcherAssert.assertThat
32import org.junit.Test
33import org.junit.runner.RunWith
34import org.junit.runners.JUnit4
35
36@RunWith(JUnit4::class)
37class NavParserTest {
38
39    @Test
40    fun test() {
41        val id: (String) -> ResReference = { id -> ResReference("a.b", "id", id) }
42        val navGraph = NavParser.parseNavigationFile(testData("naive_test.xml"),
43            "a.b", "foo.app", Context())
44
45        val nameFirst = ClassName.get("androidx.navigation.testapp", "MainFragment")
46        val nameNext = ClassName.get("foo.app", "NextFragment")
47        val expectedFirst = Destination(id("first_screen"), nameFirst, "fragment",
48                listOf(Argument("myarg1", STRING, StringValue("one"))),
49                listOf(Action(id("next"), id("next_fragment"), listOf(
50                        Argument("myarg2", STRING),
51                        Argument("randomArgument", STRING),
52                        Argument("intArgument", INT, IntValue("261"))
53                ))))
54
55        val expectedNext = Destination(id("next_fragment"), nameNext, "fragment",
56                listOf(Argument("myarg2", STRING)),
57                listOf(Action(id("next"), id("first_screen")),
58                        Action(id("finish"), null)))
59
60        val expectedGraph = Destination(null, null, "navigation", emptyList(), emptyList(),
61                listOf(expectedFirst, expectedNext))
62        assertThat(navGraph, `is`(expectedGraph))
63    }
64
65    @Test
66    fun testReferenceParsing() {
67        assertThat(parseReference("@+id/next", "a.b"), `is`(ResReference("a.b", "id", "next")))
68        assertThat(parseReference("@id/next", "a.b"), `is`(ResReference("a.b", "id", "next")))
69        assertThat(parseReference("@android:string/text", "a.b"),
70                `is`(ResReference("android", "string", "text")))
71        assertThat(parseReference("@android:id/text", "a.b"),
72                `is`(ResReference("android", "id", "text")))
73        assertThat(parseReference("@not.android:string/text", "a.b"),
74                `is`(ResReference("not.android", "string", "text")))
75    }
76
77    @Test
78    fun testIntValueParsing() {
79        assertThat(parseIntValue("foo"), nullValue())
80        assertThat(parseIntValue("10"), `is`(IntValue("10")))
81        assertThat(parseIntValue("-10"), `is`(IntValue("-10")))
82        assertThat(parseIntValue("0xA"), `is`(IntValue("0xA")))
83        assertThat(parseIntValue("0xFFFFFFFF"), `is`(IntValue("0xFFFFFFFF")))
84        assertThat(parseIntValue("0x1FFFFFFFF"), nullValue())
85    }
86
87    @Test
88    fun testArgInference() {
89        val infer = { value: String -> inferArgument("foo", value, "a.b") }
90        val intArg = { value: String -> Argument("foo", INT, IntValue(value)) }
91        val floatArg = { value: String -> Argument("foo", FLOAT, FloatValue(value)) }
92        val stringArg = { value: String -> Argument("foo", STRING, StringValue(value)) }
93        val boolArg = { value: String -> Argument("foo", BOOLEAN, BooleanValue(value)) }
94        val referenceArg = { pName: String, type: String, value: String ->
95            Argument("foo", REFERENCE, ReferenceValue(ResReference(pName, type, value)))
96        }
97
98        assertThat(infer("spb"), `is`(stringArg("spb")))
99        assertThat(infer("10"), `is`(intArg("10")))
100        assertThat(infer("0x10"), `is`(intArg("0x10")))
101        assertThat(infer("@android:id/some_la"), `is`(referenceArg("android", "id", "some_la")))
102        assertThat(infer("@foo"), `is`(stringArg("@foo")))
103        assertThat(infer("@+id/foo"), `is`(referenceArg("a.b", "id", "foo")))
104        assertThat(infer("@foo:stuff"), `is`(stringArg("@foo:stuff")))
105        assertThat(infer("@/stuff"), `is`(stringArg("@/stuff")))
106        assertThat(infer("10101010100100"), `is`(floatArg("10101010100100")))
107        assertThat(infer("1."), `is`(floatArg("1.")))
108        assertThat(infer("1.2e-4"), `is`(floatArg("1.2e-4")))
109        assertThat(infer(".4"), `is`(floatArg(".4")))
110        assertThat(infer("true"), `is`(boolArg("true")))
111        assertThat(infer("false"), `is`(boolArg("false")))
112    }
113}