androidAndroidTest.androidx.constraintlayout.core.parser.CLParserTest.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ktx-compose-constraint-layout Show documentation
Show all versions of ktx-compose-constraint-layout Show documentation
Extensions for the Kotlin standard library and third-party libraries.
The newest version!
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed 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 androidx.constraintlayout.core.parser
import org.junit.Assert
import kotlin.test.Test
class CLParserTest {
private fun testBasicFormat(content: String) {
try {
val parsedContent = CLParser.parse(content)
Assert.assertEquals(parsedContent.toJSON(), content)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testParsing() {
testBasicFormat(
"{ a: { start: ['parent', 'start', 20], " +
"top: ['parent', 'top', 30] } }"
)
testBasicFormat("{ test: 'hello, the', key: 'world' }")
testBasicFormat("{ test: [1, 2, 3] }")
testBasicFormat("{ test: ['hello', 'world', { value: 42 }] }")
testBasicFormat("{ test: [null] }")
testBasicFormat("{ test: [null, false, true] }")
testBasicFormat(
"{ test: ['hello', 'world', { value: 42 }], value: false, " +
"plop: 23, hello: { key: 42, text: 'bonjour' } }"
)
}
@Test
fun testValue() {
try {
val test = "{ test: ['hello', 'world', { value: 42 }], value: false, plop: 23, " +
"hello: { key: 49, text: 'bonjour' } }"
val parsedContent = CLParser.parse(test)
Assert.assertTrue(parsedContent.toJSON() == test)
Assert.assertEquals("hello", parsedContent.getArray("test").getString(0))
Assert.assertEquals("world", parsedContent.getArray("test").getString(1))
Assert.assertEquals(42, parsedContent.getArray("test").getObject(2)["value"].int.toLong())
Assert.assertEquals(false, parsedContent.getBoolean("value"))
Assert.assertEquals(23, parsedContent.getInt("plop").toLong())
Assert.assertEquals(49, parsedContent.getObject("hello").getInt("key").toLong())
Assert.assertEquals("bonjour", parsedContent.getObject("hello").getString("text"))
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testException() {
try {
val test = "{ test: ['hello', 'world', { value: 42 }], value: false, " +
"plop: 23, hello: { key: 49, text: 'bonjour' } }"
val parsedContent = CLParser.parse(test)
parsedContent.getObject("test").getString(0)
} catch (e: CLParsingException) {
Assert.assertEquals(
"no object found for key , found [CLArray] : " +
"CLArray (9 : 39) <<'hello', 'world', { value: 42 }>> = >; CLString (19 : 23) <>; CLObject (28 : 39) " +
"<< value: 42 }>> = > = > > > > (CLObject at line 1)", e.reason()
)
e.printStackTrace()
}
}
@Test
fun testTrailingCommas() {
try {
val test = "{ test: ['hello', 'world'],,,,,,, }"
val parsedContent = CLParser.parse(test)
Assert.assertEquals("hello", parsedContent.getArray("test").getString(0))
Assert.assertEquals("world", parsedContent.getArray("test").getString(1))
Assert.assertEquals("{ test: ['hello', 'world'] }", parsedContent.toJSON())
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testIncompleteObject() {
try {
val test = "{ test: ['hello', 'world"
val parsedContent = CLParser.parse(test)
Assert.assertEquals("hello", parsedContent.getArray("test").getString(0))
Assert.assertEquals("world", parsedContent.getArray("test").getString(1))
Assert.assertEquals("{ test: ['hello', 'world'] }", parsedContent.toJSON())
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testDoubleQuotes() {
try {
val test = "{ test: [\"hello\", \"world\"] }"
val parsedContent = CLParser.parse(test)
Assert.assertEquals("hello", parsedContent.getArray("test").getString(0))
Assert.assertEquals("world", parsedContent.getArray("test").getString(1))
Assert.assertEquals("{ test: ['hello', 'world'] }", parsedContent.toJSON())
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testDoubleQuotesKey() {
try {
val test = "{ \"test\": [\"hello\", \"world\"] }"
val parsedContent = CLParser.parse(test)
Assert.assertEquals("{ test: ['hello', 'world'] }", parsedContent.toJSON())
Assert.assertEquals("hello", parsedContent.getArray("test").getString(0))
Assert.assertEquals("world", parsedContent.getArray("test").getString(1))
Assert.assertEquals("{ test: ['hello', 'world'] }", parsedContent.toJSON())
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testMultilines() {
val test = """{
firstName: 'John',
lastName: 'Smith',
isAlive: true,
age: 27,
address: {
streetAddress: '21 2nd Street',
city: 'New York',
state: 'NY',
postalCode: '10021-3100'
},
phoneNumbers: [
{
type: 'home',
number: '212 555-1234'
},
{
type: 'office',
number: '646 555-4567'
}
],
children: [],
spouse: null
} """
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals("John", parsedContent.getString("firstName"))
Assert.assertEquals(
"{ firstName: 'John', lastName: 'Smith', isAlive: true, " +
"age: 27, address: { streetAddress: '21 2nd Street', city: 'New York', " +
"state: 'NY', postalCode: '10021-3100' }, " +
"phoneNumbers: [{ type: 'home', number: '212 555-1234' }, " +
"{ type: 'office', number: '646 555-4567' }], " +
"children: [], spouse: null }",
parsedContent.toJSON()
)
Assert.assertEquals(2, parsedContent.getArray("phoneNumbers").size().toLong())
val element = parsedContent["spouse"]
if (element is CLToken) {
Assert.assertEquals(CLToken.Type.NULL, element.type)
}
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testDoubleQuotesMultilines() {
val test = """{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
} """
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals("John", parsedContent.getString("firstName"))
Assert.assertEquals(
"{ firstName: 'John', lastName: 'Smith', isAlive: true, " +
"age: 27, address: { streetAddress: '21 2nd Street', city: 'New York', " +
"state: 'NY', postalCode: '10021-3100' }, " +
"phoneNumbers: [{ type: 'home', number: '212 555-1234' }, " +
"{ type: 'office', number: '646 555-4567' }], " +
"children: [], spouse: null }", parsedContent.toJSON()
)
Assert.assertEquals(2, parsedContent.getArray("phoneNumbers").size().toLong())
val element = parsedContent["spouse"]
if (element is CLToken) {
Assert.assertEquals(CLToken.Type.NULL, element.type)
}
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testJSON5() {
val test = """{
// comments
unquoted: 'and you can quote me on that',
singleQuotes: 'I can use "double quotes" here',
leadingDecimalPoint: .8675309, andTrailing: 8675309.,
positiveSign: +1,
trailingComma: 'in objects', andIn: ['arrays',],
"backwardsCompatible": "with JSON",
}"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"{ unquoted: 'and you can quote me on that', " +
"singleQuotes: 'I can use \"double quotes\" here', " +
"leadingDecimalPoint: 0.8675309, andTrailing: 8675309, " +
"positiveSign: 1, trailingComma: 'in objects', " +
"andIn: ['arrays'], backwardsCompatible: 'with JSON' }",
parsedContent.toJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testConstraints() {
val test = """{
g1 : { type: 'vGuideline', start: 44 },
g2 : { type: 'vGuideline', end: 44 },
image: {
width: 201, height: 179,
top: ['parent','top', 32],
start: 'g1'
},
"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"{ g1: { type: 'vGuideline', start: 44 }, " +
"g2: { type: 'vGuideline', end: 44 }, " +
"image: { width: 201, height: 179, top: ['parent', 'top', 32], " +
"start: 'g1' } }",
parsedContent.toJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testConstraints2() {
val test = """ {
Variables: {
bottom: 20
},
Helpers: [
['hChain', ['a','b','c'], {
start: ['leftGuideline1', 'start'],
style: 'packed'
}],
['hChain', ['d','e','f']],
['vChain', ['d','e','f'], {
bottom: ['topGuideline1', 'top']
}],
['vGuideline', {
id: 'leftGuideline1', start: 100
}],
['hGuideline', {
id: 'topGuideline1', percent: 0.5
}]
],
a: {
bottom: ['b', 'top', 'bottom']
},
b: {
width: '30%',
height: '1:1',
centerVertically: 'parent'
},
c: {
top: ['b', 'bottom']
}
}"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"{ " +
"Variables: { bottom: 20 }, " +
"Helpers: [" +
"['hChain', ['a', 'b', 'c'], { start: ['leftGuideline1', 'start'], style: 'packed' }], " +
"['hChain', ['d', 'e', 'f']], " +
"['vChain', ['d', 'e', 'f'], { bottom: ['topGuideline1', 'top'] }], " +
"['vGuideline', { id: 'leftGuideline1', start: 100 }], " +
"['hGuideline', { id: 'topGuideline1', percent: 0.5 }]" +
"], " +
"a: { bottom: ['b', 'top', 'bottom'] }, " +
"b: { width: '30%', height: '1:1', centerVertically: 'parent' }, " +
"c: { top: ['b', 'bottom'] } }",
parsedContent.toJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testConstraints3() {
val test = """{
ConstraintSets: {
start: {
a: {
width: 40,
height: 40,
start: ['parent', 'start', 16],
bottom: ['parent', 'bottom', 16]
}
},
end: {
a: {
width: 40,
height: 40,
//rotationZ: 390,
end: ['parent', 'end', 16],
top: ['parent', 'top', 16]
}
}
},
Transitions: {
default: {
from: 'start',
to: 'end',
pathMotionArc: 'startHorizontal',
KeyFrames: {
// KeyPositions: [
// {
// target: ['a'],
// frames: [25, 50, 75],
//// percentX: [0.4, 0.8, 0.1],
//// percentY: [0.4, 0.8, 0.3]
// }
// ],
KeyAttributes: [
{
target: ['a'],
frames: [25, 50],
scaleX: 3,
scaleY: .3
}
]
}
}
}
}"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"{ ConstraintSets: { start: { a: { width: 40, height: 40, start: ['parent', 'start', 16], bottom: ['parent', 'bottom', 16] } }, end: { a: { width: 40, height: 40, end: ['parent', 'end', 16], top: ['parent', 'top', 16] } } }, Transitions: { default: { from: 'start', to: 'end', pathMotionArc: 'startHorizontal', KeyFrames: { KeyAttributes: [{ target: ['a'], frames: [25, 50], scaleX: 3, scaleY: 0.3 }] } } } }",
parsedContent.toJSON()
)
val transitions = parsedContent.getObject("Transitions")
val transition = transitions.getObject("default")
val keyframes = transition.getObjectOrNull("KeyFrames")
val keyattributes = keyframes!!.getArrayOrNull("KeyAttributes")
Assert.assertNotNull(keyattributes)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
Assert.assertTrue(false)
}
}
@Test
fun testFormatting() {
val test = "{ firstName: 'John', lastName: 'Smith', isAlive: true, " +
"age: 27, address: { streetAddress: '21 2nd Street', city: 'New York', " +
"state: 'NY', postalCode: '10021-3100' }, " +
"phoneNumbers: [{ type: 'home', number: '212 555-1234' }, " +
"{ type: 'office', number: '646 555-4567' }], " +
"children: [], spouse: null }"
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
firstName: 'John',
lastName: 'Smith',
isAlive: true,
age: 27,
address: {
streetAddress: '21 2nd Street',
city: 'New York',
state: 'NY',
postalCode: '10021-3100'
},
phoneNumbers: [
{
type: 'home',
number: '212 555-1234'
},
{
type: 'office',
number: '646 555-4567'
}
],
children: [],
spouse: null
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting2() {
val test = "{ ConstraintSets: { start: { a: { width: 40, height: 40, " +
"start: ['parent', 'start', 16], bottom: ['parent', 'bottom', 16] } }, end: " +
"{ a: { width: 40, height: 40, end: ['parent', 'end', 16], top: ['parent', 'top', 16]" +
" } } }, Transitions: { default: { from: 'start', to: 'end', " +
"pathMotionArc: 'startHorizontal', KeyFrames: { KeyAttributes: [{ target: ['a'], " +
"frames: [25, 50], scaleX: 3, scaleY: 0.3 }] } } } }"
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
ConstraintSets: {
start: {
a: {
width: 40,
height: 40,
start: ['parent', 'start', 16],
bottom: ['parent', 'bottom', 16]
}
},
end: {
a: {
width: 40,
height: 40,
end: ['parent', 'end', 16],
top: ['parent', 'top', 16]
}
}
},
Transitions: {
default: {
from: 'start',
to: 'end',
pathMotionArc: 'startHorizontal',
KeyFrames: {
KeyAttributes: [
{
target: ['a'],
frames: [25, 50],
scaleX: 3,
scaleY: 0.3
}
]
}
}
}
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting3() {
val test = """{ ConstraintSets: {
Generate: { texts: { top: ['parent', 'top', 'margin'], start: ['parent', 'end', 16] } } } }
"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
ConstraintSets: {
Generate: {
texts: {
top: ['parent', 'top', 'margin'],
start: ['parent', 'end', 16]
}
}
}
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting4() {
val test = "{ Transitions: { default: { from: 'start', to: 'end', " +
"pathMotionArc: 'startHorizontal', KeyFrames: { KeyAttributes: [{ target: ['a'], " +
"frames: [25, 50], scaleX: 3, scaleY: 0.3 }] } } } }"
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
Transitions: {
default: {
from: 'start',
to: 'end',
pathMotionArc: 'startHorizontal',
KeyFrames: {
KeyAttributes: [
{
target: ['a'],
frames: [25, 50],
scaleX: 3,
scaleY: 0.3
}
]
}
}
}
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting5() {
val test = """{ Debug: { name: 'motion6' }, ConstraintSets: {
start: { Variables: { texts: { tag: 'text' }, margin: { from: 0, step: 50 }
}, Generate: { texts: { top: ['parent', 'top', 'margin'], start: ['parent', 'end', 16] }
}, box: { width: 'spread', height: 64, centerHorizontally: 'parent',
bottom: ['parent', 'bottom'] }, content: { width: 'spread',
height: '400', centerHorizontally: 'parent', top: ['box', 'bottom', 32]
}, name: { centerVertically: 'box', start: ['parent', 'start', 16] }
}, end: { Variables: { texts: { tag: 'text' },
margin: { from: 0, step: 50 } }, Generate: {
texts: { start: ['parent', 'start', 32], top: ['content', 'top', 'margin'] }
}, box: { width: 'spread', height: 200, centerHorizontally: 'parent',
top: ['parent', 'top'] }, content: {
width: 'spread', height: 'spread', centerHorizontally: 'parent',
top: ['box', 'bottom'], bottom: ['parent', 'bottom']
}, name: { rotationZ: 90, scaleX: 2, scaleY: 2,
end: ['parent', 'end', 16], top: ['parent', 'top', 90]
} } }, Transitions: { default: { from: 'start', to: 'end',
pathMotionArc: 'startHorizontal', KeyFrames: {
KeyAttributes: [ { target: ['box', 'content'],
frames: [50], rotationZ: [25], rotationY: [25]
} ] } } } }"""
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
Debug: { name: 'motion6' },
ConstraintSets: {
start: {
Variables: {
texts: {
tag: 'text'
},
margin: {
from: 0,
step: 50
}
},
Generate: {
texts: {
top: ['parent', 'top', 'margin'],
start: ['parent', 'end', 16]
}
},
box: {
width: 'spread',
height: 64,
centerHorizontally: 'parent',
bottom: ['parent', 'bottom']
},
content: {
width: 'spread',
height: '400',
centerHorizontally: 'parent',
top: ['box', 'bottom', 32]
},
name: { centerVertically: 'box', start: ['parent', 'start', 16] }
},
end: {
Variables: {
texts: {
tag: 'text'
},
margin: {
from: 0,
step: 50
}
},
Generate: {
texts: {
start: ['parent', 'start', 32],
top: ['content', 'top', 'margin']
}
},
box: {
width: 'spread',
height: 200,
centerHorizontally: 'parent',
top: ['parent', 'top']
},
content: {
width: 'spread',
height: 'spread',
centerHorizontally: 'parent',
top: ['box', 'bottom'],
bottom: ['parent', 'bottom']
},
name: {
rotationZ: 90,
scaleX: 2,
scaleY: 2,
end: ['parent', 'end', 16],
top: ['parent', 'top', 90]
}
}
},
Transitions: {
default: {
from: 'start',
to: 'end',
pathMotionArc: 'startHorizontal',
KeyFrames: {
KeyAttributes: [
{
target: ['box', 'content'],
frames: [50],
rotationZ: [25],
rotationY: [25]
}
]
}
}
}
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting6() {
val test = "{ root: {interpolated: {left: 0, top: 0, right: 800, bottom: 772}}, " +
"button: {interpolated: {left: 0, top: 372, right: 800, bottom: 401}}, " +
"text1: {interpolated: {left: 100, top: 285, right: 208, bottom: 301}}, " +
"text2: {interpolated: {left: 723, top: 736, right: 780, bottom: 752}}, " +
"g1: {type: 'vGuideline',interpolated: {left: 100, top: 0, right: 100, bottom: 772}}, }"
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
root: { interpolated: { left: 0, top: 0, right: 800, bottom: 772 } },
button: { interpolated: { left: 0, top: 372, right: 800, bottom: 401 } },
text1: { interpolated: { left: 100, top: 285, right: 208, bottom: 301 } },
text2: { interpolated: { left: 723, top: 736, right: 780, bottom: 752 } },
g1: {
type: 'vGuideline',
interpolated: { left: 100, top: 0, right: 100, bottom: 772 }
}
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting7() {
val test = "{ root: {left: 0, top: 0, right: 800, bottom: 772}, " +
"button: {left: 0, top: 372, right: 800, bottom: 401}, "
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
root: { left: 0, top: 0, right: 800, bottom: 772 },
button: { left: 0, top: 372, right: 800, bottom: 401 }
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
@Test
fun testFormatting8() {
val test = "{ root: { bottom: 772}, " +
"button: { bottom: 401 }, "
try {
val parsedContent = CLParser.parse(test)
Assert.assertEquals(
"""{
root: { bottom: 772 },
button: { bottom: 401 }
}""", parsedContent.toFormattedJSON()
)
} catch (e: CLParsingException) {
println("Exception " + e.reason())
e.printStackTrace()
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy