@@ -10,35 +10,94 @@ import com.orbitalhq.query.QueryResult
1010import com.orbitalhq.rawObjects
1111import com.orbitalhq.schemaServer.core.adaptors.taxi.TaxiSchemaSourcesAdaptor
1212import com.orbitalhq.schemaServer.core.file.FileProjectSpec
13+ import com.orbitalhq.schemaServer.core.file.packages.FileSystemPackageLoader
1314import com.orbitalhq.schemas.taxi.TaxiSchema
1415import com.orbitalhq.stubbing.StubService
1516import com.orbitalhq.testVyne
17+ import com.orbitalhq.utils.files.ReactivePollingFileSystemMonitor
18+ import io.kotest.assertions.AssertionFailedError
1619import io.kotest.assertions.fail
1720import io.kotest.assertions.withClue
21+ import io.kotest.core.extensions.TestCaseExtension
22+ import io.kotest.core.listeners.AfterTestListener
1823import io.kotest.core.listeners.BeforeSpecListener
1924import io.kotest.core.spec.Spec
25+ import io.kotest.core.test.TestCase
26+ import io.kotest.core.test.TestResult
27+ import kotlinx.coroutines.withContext
2028import lang.taxi.CompilationException
2129import lang.taxi.TaxiDocument
2230import lang.taxi.packages.TaxiPackageLoader
23- import lang.taxi.packages.TaxiPackageProject
31+ import lang.taxi.query.TaxiQLQueryString
32+ import org.taxilang.packagemanager.DefaultDependencyFetcherProvider
33+ import org.taxilang.packagemanager.DependencyFetcherProvider
2434import java.nio.file.Path
2535import java.nio.file.Paths
26- import kotlin.io.path.absolute
27- import com.orbitalhq.schemaServer.core.file.packages.FileSystemPackageLoader
28- import com.orbitalhq.utils.files.ReactivePollingFileSystemMonitor
29- import io.kotest.assertions.AssertionFailedError
30- import io.kotest.core.extensions.TestCaseExtension
31- import io.kotest.core.listeners.AfterTestListener
32- import io.kotest.core.test.TestCase
33- import io.kotest.core.test.TestResult
34- import kotlinx.coroutines.withContext
35- import lang.taxi.query.TaxiQLQueryString
3636import java.time.Duration
3737import kotlin.coroutines.CoroutineContext
3838import kotlin.coroutines.coroutineContext
39+ import kotlin.io.path.absolute
40+
41+ sealed interface PreflightSourceConfig {
42+ fun loadSchema (environmentVariables : Map <String ,String > = emptyMap()): TaxiSchema
43+ }
3944
40- class PreflightExtension (val projectRoot : Path = Paths .get("./")) : BeforeSpecListener, AfterTestListener,
41- TestCaseExtension {
45+ class FilePathSourceConfig (
46+ private val projectRoot : Path = Paths .get("./"),
47+ private val dependencyFetcherProvider : DependencyFetcherProvider = DefaultDependencyFetcherProvider
48+ ) : PreflightSourceConfig {
49+ override fun loadSchema (environmentVariables : Map <String , String >): TaxiSchema {
50+ val loader = TaxiPackageLoader .forDirectoryContainingTaxiFile(projectRoot.absolute().normalize())
51+ val taxiProject = loader.load()
52+ val sourcePackage = loadSourcePackage(taxiProject.packageRootPath!! )
53+
54+ return withClue(" Taxi project should compile without errors" ) {
55+ val taxiSchema = try {
56+ TaxiSchema .from(
57+ sourcePackage,
58+ environmentVariables = environmentVariables,
59+ onErrorBehaviour = TaxiSchema .Companion .TaxiSchemaErrorBehaviour .THROW_EXCEPTION
60+ )
61+ } catch (e: CompilationException ) {
62+ fail(" Taxi project has errors: \n ${e.message} " )
63+ }
64+ taxiSchema
65+ }
66+ }
67+
68+ /* *
69+ * Loads a source path into a SourcePackage
70+ * Uses the orbital approach of loading (using a FileSystemPackageLoader)
71+ * rather than a simple TaxiPackageLoader, as we need to support transpilation of non-taxi sources
72+ */
73+ private fun loadSourcePackage (packageRootPath : Path ): SourcePackage {
74+ val spec = FileProjectSpec (path = packageRootPath)
75+ val fileMonitor = ReactivePollingFileSystemMonitor (packageRootPath, Duration .ofHours(9999 ))
76+ val converter = TaxiSchemaSourcesAdaptor (
77+ dependencyFetcherProvider = dependencyFetcherProvider
78+ )
79+ val packageLoader = FileSystemPackageLoader (spec, converter, fileMonitor)
80+ val packageMetadata = converter.buildMetadata(packageLoader)
81+ .block()!!
82+ val sourcePackage = converter.convert(packageMetadata, packageLoader).block()!!
83+ return sourcePackage
84+ }
85+ }
86+
87+ class StringSourceConfig (private val source : String ) : PreflightSourceConfig {
88+ override fun loadSchema (environmentVariables : Map <String , String >): TaxiSchema {
89+ return TaxiSchema .from(source, environmentVariables = environmentVariables)
90+ }
91+ }
92+
93+ fun forSchema (source : String ) = StringSourceConfig (source)
94+
95+ class PreflightExtension (private val sourceConfig : PreflightSourceConfig = FilePathSourceConfig (),
96+ private val envVariableContainer : EnvVariableContainer = SpecEnvVariables .newInstance()
97+ ) : BeforeSpecListener,
98+ AfterTestListener ,
99+ TestCaseExtension ,
100+ EnvVariableContainer by envVariableContainer {
42101
43102 companion object {
44103 val PreflightTestCaseKey = object : CoroutineContext .Key <PreflightTestCaseContext > {}
@@ -54,14 +113,7 @@ class PreflightExtension(val projectRoot: Path = Paths.get("./")) : BeforeSpecLi
54113 lateinit var schema: TaxiSchema
55114 private set
56115
57- lateinit var sourcePackage: SourcePackage
58- private set
59-
60- /* *
61- * Provides access to the actual Taxi project (the equivalent of the
62- * taxi.conf file)
63- */
64- lateinit var taxiProject: TaxiPackageProject
116+ private lateinit var sourcePackage: SourcePackage
65117 private set
66118
67119 private val capturedScenarios = mutableMapOf<TestCase , CapturedQuery >()
@@ -71,10 +123,7 @@ class PreflightExtension(val projectRoot: Path = Paths.get("./")) : BeforeSpecLi
71123 envVariableContainer.markImmutable()
72124 withClue(" Taxi project should compile without errors" ) {
73125 val taxiSchema = try {
74- TaxiSchema .from(
75- sourcePackage,
76- onErrorBehaviour = TaxiSchema .Companion .TaxiSchemaErrorBehaviour .THROW_EXCEPTION
77- )
126+ sourceConfig.loadSchema(environmentVariables = envVariableContainer.envVariables)
78127 } catch (e: CompilationException ) {
79128 fail(" Taxi project has errors: \n ${e.message} " )
80129 }
@@ -84,23 +133,8 @@ class PreflightExtension(val projectRoot: Path = Paths.get("./")) : BeforeSpecLi
84133 }
85134 }
86135
87- /* *
88- * Loads a source path into a SourcePackage
89- * Uses the orbital approach of loading (using a FileSystemPackageLoader)
90- * rather than a simple TaxiPackageLoader, as we need to support transpilation of non-taxi sources
91- */
92- private fun loadSourcePackage (packageRootPath : Path ): SourcePackage {
93- val spec = FileProjectSpec (path = packageRootPath)
94- val fileMonitor = ReactivePollingFileSystemMonitor (packageRootPath, Duration .ofHours(9999 ))
95- val packageLoader = FileSystemPackageLoader (spec, TaxiSchemaSourcesAdaptor (), fileMonitor)
96- val converter = TaxiSchemaSourcesAdaptor ()
97- val packageMetadata = converter.buildMetadata(packageLoader)
98- .block()!!
99- val sourcePackage = converter.convert(packageMetadata, packageLoader).block()!!
100- return sourcePackage
101- }
102136
103- fun orbital (): Pair <Orbital , StubService > {
137+ private fun orbital (): Pair <Orbital , StubService > {
104138 return testVyne(this .schema)
105139 }
106140
@@ -148,7 +182,26 @@ class PreflightExtension(val projectRoot: Path = Paths.get("./")) : BeforeSpecLi
148182 .firstTypedInstace()
149183 }
150184
151- suspend fun query (taxiQl : String , stubCustomizer : (StubService ) -> Unit = {}): QueryResult {
185+ suspend fun runNamedQueryForObject (queryName : String , stubCustomizer : (StubService ) -> Unit = {}) =
186+ runNamedQuery(queryName, stubCustomizer)
187+ .firstTypedInstace()
188+
189+ suspend fun runNamedQueryForStream (queryName : String , stubCustomizer : (StubService ) -> Unit = {}) =
190+ runNamedQuery(queryName, stubCustomizer).results
191+
192+ private suspend fun runNamedQuery (queryName : String , stubCustomizer : (StubService ) -> Unit = {}): QueryResult {
193+ val (orbital) = orbital()
194+ val savedQuery = orbital.schema.queries.singleOrNull {
195+ it.name.parameterizedName == queryName || it.name.name == queryName
196+ }
197+ if (savedQuery == null ) {
198+ fail(" No query named $queryName was found" )
199+ }
200+ val taxiQl = savedQuery.sources.joinToString(" \n " ) { it.content }
201+ return query(taxiQl, stubCustomizer)
202+ }
203+
204+ private suspend fun query (taxiQl : String , stubCustomizer : (StubService ) -> Unit = {}): QueryResult {
152205 val (orbital, stub) = orbital()
153206 stubCustomizer(stub)
154207 val testContext = coroutineContext[PreflightTestCaseKey ]
@@ -165,7 +218,7 @@ class PreflightExtension(val projectRoot: Path = Paths.get("./")) : BeforeSpecLi
165218 return withContext(context) {
166219 val testResult = execute(testCase)
167220 val capturedScenario = capturedScenarios[testCase]
168- if (testResult.isErrorOrFailure && capturedScenario != null ) {
221+ if (testResult.isFailure && capturedScenario != null ) {
169222
170223 val failure = testResult as TestResult .Failure
171224 val originalError = failure.cause as AssertionFailedError
@@ -204,4 +257,4 @@ data class CapturedQuery(
204257
205258data class PreflightTestCaseContext (val testCase : TestCase ) : CoroutineContext.Element {
206259 override val key = PreflightTestCaseKey
207- }
260+ }
0 commit comments