diff --git a/build.gradle.kts b/build.gradle.kts index 89de9c3..806fafe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -51,7 +51,6 @@ jacoco { } repositories { - mavenLocal() mavenCentral() } diff --git a/detekt.yml b/detekt.yml index cb0b3a6..d597b85 100644 --- a/detekt.yml +++ b/detekt.yml @@ -254,7 +254,7 @@ exceptions: active: true ignoreLabeled: false SwallowedException: - active: true + active: false ignoredExceptionTypes: - 'InterruptedException' - 'MalformedURLException' diff --git a/src/main/kotlin/org/xpathqs/core/reflection/ReflectionExtensions.kt b/src/main/kotlin/org/xpathqs/core/reflection/ReflectionExtensions.kt index 6ada55e..446a664 100644 --- a/src/main/kotlin/org/xpathqs/core/reflection/ReflectionExtensions.kt +++ b/src/main/kotlin/org/xpathqs/core/reflection/ReflectionExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,11 @@ import org.xpathqs.core.selector.block.Block import org.xpathqs.core.selector.group.GroupSelector import kotlin.reflect.KClass import kotlin.reflect.KProperty +import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.superclasses +import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaField +import kotlin.reflect.jvm.javaGetter /** * Set of functional extensions to manipulate with
selectors
via Reflection @@ -212,15 +215,25 @@ internal fun Any.isInnerClass(): Boolean { return getInnerClassMember() != null } +fun KProperty<*>.isDeclaredInInnerClass(): Boolean { + val declaring = javaField?.declaringClass + ?: javaGetter?.declaringClass + ?: return false + if(declaring.name.endsWith("\$${declaring.simpleName}")) { + println() + } + return declaring.name.endsWith("\$${declaring.simpleName}") +} + /** * Return member of inner class */ internal fun Any.getInnerClassMember(): Any? { - val f = this::class.java.declaredFields.find { - it.name.contains("this$") + val f = this::class.declaredMemberProperties.firstOrNull{ + it.isDeclaredInInnerClass() } f?.isAccessible = true - return f?.get(this) + return f?.call(this) } /** diff --git a/src/main/kotlin/org/xpathqs/core/selector/base/CoreExtensions.kt b/src/main/kotlin/org/xpathqs/core/selector/base/CoreExtensions.kt index 8748430..4d65f55 100644 --- a/src/main/kotlin/org/xpathqs/core/selector/base/CoreExtensions.kt +++ b/src/main/kotlin/org/xpathqs/core/selector/base/CoreExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,10 @@ package org.xpathqs.core.selector.base import org.xpathqs.core.reflection.* import org.xpathqs.core.selector.block.Block +//import org.xpathqs.core.util.SelectorFactory import java.lang.reflect.Constructor +import java.lang.reflect.Modifier +import kotlin.reflect.full.primaryConstructor /** * @return an ability of [Block] object to be cloned @@ -72,6 +75,18 @@ fun T.deepClone(): T { return newObj } +fun getOuterInstance(innerInstance: Any): Any? { + val innerClass = innerInstance.javaClass + return try { + val field = innerClass.getDeclaredField("this$0") + field.isAccessible = true + field.get(innerInstance) + } catch (e: NoSuchFieldException) { + // The field might have a different name or not exist. + null + } +} + /** * @return new instance of object class with the default properties * @@ -100,11 +115,49 @@ fun T.deepClone(): T { * Require #7 - ability to instantiate a [Block] class-object * @sample org.xpathqs.core.selector.base.extension.NewInstanceTest.r7_newInstanceForBlockObject */ + @Suppress("UNCHECKED_CAST") internal fun T.newInstance(): T { + + fun cloneSingleton(original: Any): Any { + val clazz = original::class.java + + // 1. Get the private no‑arg constructor + val constructor = clazz.getDeclaredConstructor() + constructor.isAccessible = true + + // 2. Create a new instance (this breaks the singleton) + val clone = constructor.newInstance() + + // 3. Copy all non‑static fields from the original to the clone + for (field in clazz.declaredFields) { + if (!Modifier.isStatic(field.modifiers)) { + field.isAccessible = true + field.set(clone, field.get(original)) + } + } + return clone + } + val res = if (this.isInnerClass()) { - val c = this.getConstructor(1) - c.newInstance(this.getInnerClassMember()) + if(this::class.isObject()) { + return cloneSingleton(this) as T + } + if(this::class.isInner) { + val outer = getOuterInstance(this) + val c = this::class.primaryConstructor + val p = c!!.parameters + c.callBy( + mapOf(p[0] to outer) + ) + } else { + if(this::class.primaryConstructor?.parameters?.size == 0) { + this::class.primaryConstructor!!.call() + } else { + val c = this.getConstructor(1) + c.newInstance(this.getInnerClassMember()) + } + } } else { val c = this.getConstructor(0) c.newInstance() diff --git a/src/main/kotlin/org/xpathqs/core/selector/extensions/SelectorArgExtensions.kt b/src/main/kotlin/org/xpathqs/core/selector/extensions/SelectorArgExtensions.kt index 365e94a..9b39e16 100644 --- a/src/main/kotlin/org/xpathqs/core/selector/extensions/SelectorArgExtensions.kt +++ b/src/main/kotlin/org/xpathqs/core/selector/extensions/SelectorArgExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,8 @@ import org.xpathqs.core.selector.args.decorators.ContainsDecorator import org.xpathqs.core.selector.args.decorators.KVNormalizeSpaceDecorator import org.xpathqs.core.selector.base.BaseSelector import org.xpathqs.core.selector.extensions.core.clone +import org.xpathqs.core.selector.group.GroupSelector +import org.xpathqs.core.selector.group.addGroupArg /** * Add `text` argument query @@ -69,10 +71,7 @@ fun T.arg( argName: String, value: String, contains: Boolean = false, - normalize: Boolean = false -) = selfClone { - val res = this.clone() - + normalize: Boolean = false): T { var arg: ValueArg = CommaDecorator(KVSelectorArg(argName, value)) @@ -84,9 +83,10 @@ fun T.arg( arg = ContainsDecorator(arg as KVSelectorArg) } - res.props.args.add( - arg - ) + return when (this) { + is GroupSelector -> this.addGroupArg(arg) + else -> this.addArg(arg) + } } /** diff --git a/src/main/kotlin/org/xpathqs/core/selector/group/GroupSelectorModificationExtensions.kt b/src/main/kotlin/org/xpathqs/core/selector/group/GroupSelectorModificationExtensions.kt index c052024..8409058 100644 --- a/src/main/kotlin/org/xpathqs/core/selector/group/GroupSelectorModificationExtensions.kt +++ b/src/main/kotlin/org/xpathqs/core/selector/group/GroupSelectorModificationExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -72,23 +72,19 @@ fun T.prefix(value: String): T { /** - * Modifies `prefix` value of [GroupSelector] + * Modifies `postfix` value of [GroupSelector] * - * Require #1 - Prefix should be updated only when [GroupSelector.selectorsChain] - * has first [Selector] element. It is actual for the Block elements + * Require #1 - postfix should be updated only when [GroupSelector.selectorsChain] + * has last [Selector] element. It is actual for the Block elements * @sample [org.xpathqs.core.selector.group.extensions.PrefixTest.r1_prefixWithSelector] * - * Require #2 - prefix should be ignored when first selector is not a [Selector] object - * @sample [org.xpathqs.core.selector.group.extensions.PrefixTest.r2_prefixWithXpathSelector] */ fun T.postfix(value: String): T { - val first = this.selectorsChain.first() - if (first is Selector) { + val last = this.selectorsChain.last() + if (last is Selector) { val res = this.clone() - val chain: ArrayList = arrayListOf(first.postfix(value)) - this.selectorsChain.removeFirst() - chain.addAll(this.selectorsChain) - res.selectorsChain = chain + this.selectorsChain.removeLast() + res.selectorsChain = ArrayList( this.selectorsChain + last.postfix(value)) return res } diff --git a/src/main/kotlin/org/xpathqs/core/util/SelectorFactory.kt b/src/main/kotlin/org/xpathqs/core/util/SelectorFactory.kt index fb586e0..aa3615d 100644 --- a/src/main/kotlin/org/xpathqs/core/util/SelectorFactory.kt +++ b/src/main/kotlin/org/xpathqs/core/util/SelectorFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,8 +32,6 @@ import org.xpathqs.core.selector.args.decorators.KVNormalizeSpaceDecorator import org.xpathqs.core.selector.base.ISelector import org.xpathqs.core.selector.compose.ComposeSelector import org.xpathqs.core.selector.compose.ComposeSelectorProps -import org.xpathqs.core.selector.extensions.addArg -import org.xpathqs.core.selector.extensions.addStringToArgs import org.xpathqs.core.selector.selector.Selector import org.xpathqs.core.selector.selector.SelectorProps import org.xpathqs.core.selector.xpath.XpathSelector diff --git a/src/test/kotlin/org/xpathqs/core/reflection/SingleBaseTest.kt b/src/test/kotlin/org/xpathqs/core/reflection/SingleBaseTest.kt index 3cb2771..fc1e9fa 100644 --- a/src/test/kotlin/org/xpathqs/core/reflection/SingleBaseTest.kt +++ b/src/test/kotlin/org/xpathqs/core/reflection/SingleBaseTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,9 +56,9 @@ class SingleBaseTest : AnnotationSpec() { fun r1_forSelector() { WHEN { ForTest().parse().s1.toXpath() - }.THEN { + }.THEN( "//base/div" - } + ) } /** @@ -71,9 +71,9 @@ class SingleBaseTest : AnnotationSpec() { ForTestObj.parse() }.WHEN { ForTestObj.InnerObj.s1.toXpath() - }.THEN { + }.THEN( "//base/div" - } + ) } /** @@ -84,9 +84,9 @@ class SingleBaseTest : AnnotationSpec() { fun r3_forGroupSelector() { WHEN { ForTest().parse().s2.toXpath() - }.THEN { + }.THEN( "//base/div//div" - } + ) } /** @@ -99,9 +99,9 @@ class SingleBaseTest : AnnotationSpec() { ForTestObj.parse() }.WHEN { ForTestObj.InnerObj.s2.toXpath() - }.THEN { + }.THEN( "//base/div" - } + ) } /** @@ -114,8 +114,8 @@ class SingleBaseTest : AnnotationSpec() { ForTestObj.parse() }.WHEN { ForTestObj.InnerObj.s3.toXpath() - }.THEN { + }.THEN( "//base//div" - } + ) } } diff --git a/src/test/kotlin/org/xpathqs/core/reflection/extensions/ReflectionExtensionsTest.kt b/src/test/kotlin/org/xpathqs/core/reflection/extensions/ReflectionExtensionsTest.kt index 8493efe..c5809dd 100644 --- a/src/test/kotlin/org/xpathqs/core/reflection/extensions/ReflectionExtensionsTest.kt +++ b/src/test/kotlin/org/xpathqs/core/reflection/extensions/ReflectionExtensionsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,9 @@ import org.xpathqs.gwt.GIVEN class ReflectionExtensionsTest : AnnotationSpec() { class TestCls { - inner class InnerCls + class InnerCls { + val m1: String = "test1" + } val innerMember = InnerCls() class Class2 val member = Class2() @@ -44,9 +46,9 @@ class ReflectionExtensionsTest : AnnotationSpec() { tagSelector("div") }.WHEN { given.isInnerClass() - }.THEN { + }.THEN( false - } + ) } /** @@ -58,8 +60,8 @@ class ReflectionExtensionsTest : AnnotationSpec() { TestCls() }.WHEN { given.innerMember.isInnerClass() - }.THEN { + }.THEN( true - } + ) } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/reflection/extensions/RootParentTest.kt b/src/test/kotlin/org/xpathqs/core/reflection/extensions/RootParentTest.kt index f68be33..88b4c12 100644 --- a/src/test/kotlin/org/xpathqs/core/reflection/extensions/RootParentTest.kt +++ b/src/test/kotlin/org/xpathqs/core/reflection/extensions/RootParentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,9 +39,9 @@ class RootParentTest : AnnotationSpec() { fun r1_rootParent() { WHEN { tagSelector("div").rootParent - }.THEN { + }.THEN( NullSelector() - } + ) } /** @@ -51,9 +51,9 @@ class RootParentTest : AnnotationSpec() { fun r2_rootParent() { WHEN { RootParent.level1.rootParent - }.THEN { + }.THEN( RootParent - } + ) } /** @@ -63,9 +63,9 @@ class RootParentTest : AnnotationSpec() { fun r3_rootParent() { WHEN { RootParent.InnerObj.level2.rootParent - }.THEN { + }.THEN( RootParent - } + ) } init { RootParent.parse() diff --git a/src/test/kotlin/org/xpathqs/core/reflection/testpackage/PackageScannerExtensions.kt b/src/test/kotlin/org/xpathqs/core/reflection/testpackage/PackageScannerExtensions.kt index f086d7b..cb6c078 100644 --- a/src/test/kotlin/org/xpathqs/core/reflection/testpackage/PackageScannerExtensions.kt +++ b/src/test/kotlin/org/xpathqs/core/reflection/testpackage/PackageScannerExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,9 +46,9 @@ class PackageScannerExtensions : AnnotationSpec() { this.javaClass.`package`.scan() }.WHEN { Page1.s1.name - }.THEN { + }.THEN( "Page1.s1" - } + ) } /** @@ -60,9 +60,9 @@ class PackageScannerExtensions : AnnotationSpec() { "org.xpathqs.core.reflection.testpage2".scanPackage() }.WHEN { Page3.s1.name - }.THEN { + }.THEN( "Page3.s1" - } + ) } /** @@ -74,8 +74,8 @@ class PackageScannerExtensions : AnnotationSpec() { scanPackage(Page2) }.WHEN { Page2.s1.name - }.THEN { + }.THEN( "Page2.s1" - } + ) } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgTest.kt b/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgTest.kt index 8462c7d..3d3dea9 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.args import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.selector.selector.preceding import org.xpathqs.core.selector.selector.prefix import org.xpathqs.core.util.SelectorFactory.tagSelector @@ -42,7 +43,7 @@ class SelectorArgTest : AnnotationSpec() { SelectorArg(given) .value }.THEN { - given.toXpath() + given.toXpath() shouldBe actual } } @@ -57,7 +58,7 @@ class SelectorArgTest : AnnotationSpec() { SelectorArg(given, type = InnerSelectorArg.ALL) .value }.THEN { - given.prefix(".//").toXpath() + given.prefix(".//").toXpath() shouldBe actual } } @@ -72,7 +73,7 @@ class SelectorArgTest : AnnotationSpec() { SelectorArg(given, type = InnerSelectorArg.ROOT) .value }.THEN { - given.prefix("./").toXpath() + given.prefix("./").toXpath() shouldBe actual } } @@ -87,7 +88,7 @@ class SelectorArgTest : AnnotationSpec() { SelectorArg(given, type = InnerSelectorArg.ROOT) .value }.THEN { - given.toXpath() + given.toXpath() shouldBe actual } } @@ -102,7 +103,7 @@ class SelectorArgTest : AnnotationSpec() { SelectorArg(given, type = InnerSelectorArg.ROOT) .value }.THEN { - "./preceding::div" + "./preceding::div" shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgsTests.kt b/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgsTests.kt index 13233a4..39ac17f 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgsTests.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/args/SelectorArgsTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -89,8 +89,8 @@ class SelectorArgsTests : AnnotationSpec() { SelectorArgs() .add(tagSelector("div")) .toXpath() - }.THEN { + }.THEN( "[//div]" - } + ) } } diff --git a/src/test/kotlin/org/xpathqs/core/selector/args/decorators/KVNormalizeSpaceDecoratorTest.kt b/src/test/kotlin/org/xpathqs/core/selector/args/decorators/KVNormalizeSpaceDecoratorTest.kt index 588d325..e8c0df0 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/args/decorators/KVNormalizeSpaceDecoratorTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/args/decorators/KVNormalizeSpaceDecoratorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.args.decorators import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.selector.args.KVSelectorArg import org.xpathqs.gwt.WHEN @@ -38,7 +39,7 @@ class KVNormalizeSpaceDecoratorTest : AnnotationSpec() { KVNormalizeSpaceDecorator(arg) .toXpath() }.THEN { - "normalize-space(text())=text" + "normalize-space(text())=text" shouldBe actual } } @@ -51,7 +52,7 @@ class KVNormalizeSpaceDecoratorTest : AnnotationSpec() { KVNormalizeSpaceDecorator(arg, normalizeK = true, normalizeV = true) .toXpath() }.THEN { - "normalize-space(text())=normalize-space(text)" + "normalize-space(text())=normalize-space(text)" shouldBe actual } } @@ -64,7 +65,7 @@ class KVNormalizeSpaceDecoratorTest : AnnotationSpec() { KVNormalizeSpaceDecorator(arg, normalizeK = false, normalizeV = false) .toXpath() }.THEN { - "text()=text" + "text()=text" shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorCustomPropsMapTest.kt b/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorCustomPropsMapTest.kt index 170e161..8f0f5da 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorCustomPropsMapTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorCustomPropsMapTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.base import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.selector.extensions.core.clone import org.xpathqs.core.util.SelectorFactory.tagSelector import org.xpathqs.gwt.GIVEN @@ -42,7 +43,7 @@ class BaseSelectorCustomPropsMapTest : AnnotationSpec() { }.WHEN { given.clone() }.THEN { - given.customPropsMap === actual.customPropsMap + (given.customPropsMap === actual.customPropsMap) shouldBe true } } diff --git a/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorToStringTest.kt b/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorToStringTest.kt index 8a95c19..c4d1d3b 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorToStringTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/base/BaseSelectorToStringTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.base import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.reflection.parse import org.xpathqs.core.selector.block.Block import org.xpathqs.core.util.SelectorFactory.tagSelector @@ -42,7 +43,7 @@ class BaseSelectorToStringTest : AnnotationSpec() { WHEN { TestCls().parse().s1.toString() }.THEN { - "TestCls.s1" + "TestCls.s1" shouldBe actual } /** @@ -54,6 +55,6 @@ class BaseSelectorToStringTest : AnnotationSpec() { WHEN { tagSelector("div").toString() }.THEN { - "//div" + "//div" shouldBe actual } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/base/extension/CanBeClonedTest.kt b/src/test/kotlin/org/xpathqs/core/selector/base/extension/CanBeClonedTest.kt index 3bc2d50..2944600 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/base/extension/CanBeClonedTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/base/extension/CanBeClonedTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.base.extension import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.reflection.parse import org.xpathqs.core.selector.base.canBeCloned import org.xpathqs.core.selector.block.Block @@ -51,7 +52,7 @@ class CanBeClonedTest : AnnotationSpec() { }.WHEN { R1.m.canBeCloned() }.THEN { - false + false shouldBe actual } } @@ -66,7 +67,7 @@ class CanBeClonedTest : AnnotationSpec() { }.WHEN { given.m.canBeCloned() }.THEN { - true + true shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/base/extension/DeepCloneTest.kt b/src/test/kotlin/org/xpathqs/core/selector/base/extension/DeepCloneTest.kt index 778bf49..cfd9ce9 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/base/extension/DeepCloneTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/base/extension/DeepCloneTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -87,7 +87,7 @@ class DeepCloneTest : AnnotationSpec() { }.WHEN { given.deepClone().state }.THEN { - SelectorState.CLONED + SelectorState.CLONED shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/base/extension/ParentsTest.kt b/src/test/kotlin/org/xpathqs/core/selector/base/extension/ParentsTest.kt index 99c377a..c6855aa 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/base/extension/ParentsTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/base/extension/ParentsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.base.extension import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.reflection.scanPackage import org.xpathqs.core.selector.block.Block import org.xpathqs.core.selector.block.allInnerSelectorBlocks @@ -64,7 +65,7 @@ class ParentsTest : AnnotationSpec() { WHEN { tagSelector("div").parents }.THEN { - emptyList() + emptyList() shouldBe actual } } @@ -76,7 +77,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.s1.parents }.THEN { - arrayListOf(Page1) + arrayListOf(Page1) shouldBe actual } } @@ -88,7 +89,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner.s1.parents }.THEN { - arrayListOf(Page1.Inner, Page1) + arrayListOf(Page1.Inner, Page1) shouldBe actual } } @@ -100,7 +101,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner isChildOf Page1 }.THEN { - true + true shouldBe actual } } @@ -112,7 +113,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1 isChildOf Page1.Inner }.THEN { - false + false shouldBe actual } } @@ -124,7 +125,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1 isChildOf Page1 }.THEN { - false + false shouldBe actual } } @@ -136,7 +137,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner2.Inner3 isChildOf Page1.allInnerSelectorBlocks }.THEN { - true + true shouldBe actual } } @@ -148,7 +149,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner isChildOf Page1.Inner2.allInnerSelectorBlocks }.THEN { - false + false shouldBe actual } } @@ -172,7 +173,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner2 isParentOf Page1.Inner }.THEN { - false + false shouldBe actual } } @@ -184,7 +185,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner isParentOf Page1.Inner }.THEN { - false + false shouldBe actual } } @@ -196,7 +197,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1 isParentOf Page1.allInnerSelectorBlocks }.THEN { - true + true shouldBe actual } } @@ -208,7 +209,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner isParentOf Page1.Inner2.allInnerSelectorBlocks }.THEN { - false + false shouldBe actual } } @@ -220,7 +221,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner doesNotChildOf Page1 }.THEN { - false + false shouldBe actual } } @@ -232,7 +233,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1.Inner doesNotChildOf Page1.allInnerSelectorBlocks }.THEN { - true + true shouldBe actual } } @@ -244,7 +245,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1 doesNotParentOf Page1.Inner }.THEN { - false + false shouldBe actual } } @@ -256,7 +257,7 @@ class ParentsTest : AnnotationSpec() { WHEN { Page1 doesNotParentOf Page1.allInnerSelectorBlocks }.THEN { - false + false shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/block/BlockSelectorXpathTest.kt b/src/test/kotlin/org/xpathqs/core/selector/block/BlockSelectorXpathTest.kt index 95c3a55..1acc059 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/block/BlockSelectorXpathTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/block/BlockSelectorXpathTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,9 +26,10 @@ import io.kotest.core.spec.style.AnnotationSpec import org.xpathqs.core.reflection.parse import org.xpathqs.core.selector.extensions.core.clone import org.xpathqs.core.selector.extensions.core.get +import org.xpathqs.core.selector.extensions.text import org.xpathqs.core.util.SelectorFactory.tagSelector -import org.xpathqs.gwt.AND import org.xpathqs.gwt.GIVEN +import org.xpathqs.xpathShouldBe class BlockSelectorXpathTest : AnnotationSpec() { object TestCls : Block( @@ -39,6 +40,7 @@ class BlockSelectorXpathTest : AnnotationSpec() { init { TestCls.parse() + } /** @@ -50,13 +52,14 @@ class BlockSelectorXpathTest : AnnotationSpec() { GIVEN { TestCls[2].s }.WHEN { - given.xpath - given.xpath - }.THEN { - "//div[position()=2]//p" - }.THEN { given.toXpath() - } + }.THEN("//div[position()=2]//p") + } + + @Test + fun checkTextArgForBlock() { + TestCls.text("ss").s + .xpathShouldBe("//div[text()='ss']//p") } /** diff --git a/src/test/kotlin/org/xpathqs/core/selector/block/CopyFromTest.kt b/src/test/kotlin/org/xpathqs/core/selector/block/CopyFromTest.kt index 6c7c7df..c881c17 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/block/CopyFromTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/block/CopyFromTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.block import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.reflection.parse import org.xpathqs.core.selector.extensions.plus import org.xpathqs.core.selector.group.GroupSelector @@ -59,7 +60,7 @@ class CopyFromTest : AnnotationSpec() { }.WHEN { given.s.toXpath() }.THEN { - "//div1//div" + "//div1//div" shouldBe actual } } @@ -75,7 +76,7 @@ class CopyFromTest : AnnotationSpec() { }.WHEN { given.s.toXpath() }.THEN { - "//div1//div" + "//div1//div" shouldBe actual } } @@ -91,7 +92,7 @@ class CopyFromTest : AnnotationSpec() { }.WHEN { given.s.toXpath() }.THEN { - "//div1//div2//div" + "//div1//div2//div" shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/block/extensions/InnerSelectorsTest.kt b/src/test/kotlin/org/xpathqs/core/selector/block/extensions/InnerSelectorsTest.kt index 5c45b93..321f0cd 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/block/extensions/InnerSelectorsTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/block/extensions/InnerSelectorsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,8 @@ package org.xpathqs.core.selector.block.extensions import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.collections.shouldContainAll +import io.kotest.matchers.shouldBe import org.xpathqs.core.reflection.parse import org.xpathqs.core.selector.block.Block import org.xpathqs.core.selector.block.allInnerSelectors @@ -107,7 +109,7 @@ class InnerSelectorsTest : AnnotationSpec() { arrayListOf( PageWithoutInner.s1, PageWithoutInner.s2 - ) + ) shouldBe actual } } @@ -122,7 +124,7 @@ class InnerSelectorsTest : AnnotationSpec() { arrayListOf( PageWithInner.s1, PageWithInner.s2 - ) + ) shouldBe actual } } @@ -131,11 +133,7 @@ class InnerSelectorsTest : AnnotationSpec() { */ @Test fun r1_selectorBlocks() { - WHEN { - PageWithoutInner.selectorBlocks - }.THEN( - arrayListOf() - ) + PageWithoutInner.selectorBlocks shouldBe arrayListOf() } /** @@ -148,7 +146,7 @@ class InnerSelectorsTest : AnnotationSpec() { }.THEN { arrayListOf( PageWithInner.Inner - ) + ) shouldBe actual } } @@ -162,7 +160,7 @@ class InnerSelectorsTest : AnnotationSpec() { }.THEN { arrayListOf( PageWithInnerClass.Inner - ) + ) shouldBe actual } } @@ -177,7 +175,7 @@ class InnerSelectorsTest : AnnotationSpec() { arrayListOf( PageWithoutInner.s1, PageWithoutInner.s2, - ) + ) shouldContainAll actual } } @@ -194,7 +192,7 @@ class InnerSelectorsTest : AnnotationSpec() { PageWithInner.s2, PageWithInner.Inner.s1, PageWithInner.Inner.s2 - ) + ) shouldContainAll actual } } @@ -212,7 +210,7 @@ class InnerSelectorsTest : AnnotationSpec() { PageWithInnerClass.Inner, PageWithInnerClass.Inner.s1, PageWithInnerClass.Inner.s2 - ) + ) shouldContainAll actual } } @@ -230,7 +228,7 @@ class InnerSelectorsTest : AnnotationSpec() { PageWithInner2.Inner.Inner2.Inner3, PageWithInner2.Inner.Inner2.Inner3.Inner4, PageWithInner2.Inner.Inner2.Inner3.Inner4.Inner5, - ) + ) shouldContainAll actual } } @@ -242,7 +240,7 @@ class InnerSelectorsTest : AnnotationSpec() { WHEN { PageWithoutInner.allInnerSelectorBlocks }.THEN { - emptyList() + emptyList() shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/group/extensions/AddGroupArgTest.kt b/src/test/kotlin/org/xpathqs/core/selector/group/extensions/AddGroupArgTest.kt index 66fb315..4e0c826 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/group/extensions/AddGroupArgTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/group/extensions/AddGroupArgTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.group.extensions import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.selector.args.ValueArg import org.xpathqs.core.selector.extensions.plus import org.xpathqs.core.selector.group.GroupSelector @@ -46,7 +47,7 @@ class AddGroupArgTest : AnnotationSpec() { ValueArg("position()=2") ).toXpath() }.THEN { - "//div[position()=2]" + "//div[position()=2]" shouldBe actual } } @@ -63,7 +64,7 @@ class AddGroupArgTest : AnnotationSpec() { ValueArg("position()=2") ).toXpath() }.THEN { - "(//div//div)[position()=2]" + "(//div//div)[position()=2]" shouldBe actual } } } \ No newline at end of file diff --git a/src/test/kotlin/org/xpathqs/core/selector/group/extensions/PrefixTest.kt b/src/test/kotlin/org/xpathqs/core/selector/group/extensions/PrefixTest.kt index 1fcaa14..dca9872 100644 --- a/src/test/kotlin/org/xpathqs/core/selector/group/extensions/PrefixTest.kt +++ b/src/test/kotlin/org/xpathqs/core/selector/group/extensions/PrefixTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 XPATH-QS + * Copyright (c) 2026 XPATH-QS * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package org.xpathqs.core.selector.group.extensions import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.shouldBe import org.xpathqs.core.selector.extensions.plus import org.xpathqs.core.selector.group.postfix import org.xpathqs.core.selector.group.prefix @@ -43,7 +44,7 @@ class PrefixTest : AnnotationSpec() { }.WHEN { given.prefix("*").toXpath() }.THEN { - "*div//div" + actual shouldBe "*div//div" } } @@ -58,12 +59,12 @@ class PrefixTest : AnnotationSpec() { }.WHEN { given.prefix("*").toXpath() }.THEN { - "//div//div" + actual shouldBe "//div//div" } } /** - * Check #3 require + * Check #1 require * @see org.xpathqs.core.selector.group.GroupSelector.postfix */ @Test @@ -73,7 +74,7 @@ class PrefixTest : AnnotationSpec() { }.WHEN { given.postfix("/*").toXpath() }.THEN { - "//div//div/*" + actual shouldBe "//div//div/*" } } } \ No newline at end of file