Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structural output of domain layer #1728

Open
jan-goral opened this issue Mar 23, 2021 · 1 comment
Open

Structural output of domain layer #1728

jan-goral opened this issue Mar 23, 2021 · 1 comment
Labels

Comments

@jan-goral
Copy link
Contributor

jan-goral commented Mar 23, 2021

Motivation

Currently, flank is putting all output data directly to console, which is useful for command-line but not for different
types of UI like the desktop.

Goal

  • Domain layer is producing structural output instead of direct logging to console.
  • Structural output from the domain layer is handled in the presentation layer.
    • CLI is converting structures into console logs and printing them.

API

/**
 * The abstraction which allows passing output from the domain to presentation.
 * Implement in domain top-level interfaces for getting access to outputting result structures.
 * @property out The reference to outputting result function.
 */
interface Output {
    val out: (Any) -> Unit
}

Steps

  1. Prepare a list of logs that can be displayed by command.
  2. Basing on a list of logs prepare corresponding structures.
  3. Extend domain top-level using Output interface
  4. Register A mapper in cli command.
  5. Replace all logLn occurrences with out function call
  6. Move the mapper to the proper package. (TODO - Consider which package is proper)

Hint

For step 2. If you have to add a new type that can be identified in the presentation layer as something that should be converted to the console log and you also have to decide where to place it, you can follow the rules:

  • If the type denotes the execution status of domain logic run, place this type in domain interface scope.
  • If the type is related to API structure, add it to this related structure scope. (This one is shown in the example)

Example

Based on ListAndroidOrientations

Step 1

  1. List<Orientation> - test_runner/src/main/kotlin/ftl/domain/ListAndroidOrientations.kt#L16

Step 2

List<Orientation> is a generic type that is losing parameter type info in runtime, so it's necessary to create a
wrapping structure that could be resolved by type matching.

Add Orientaton.Available structure for representing list available orientations the specific platform

data class Orientation(
    val id: String,
    val name: String,
    val tags: List<String>,
) {
    data class Available(
        val platform: Platform,
        val list: List<Orientation>
    )

    interface Fetch : (String, Platform) -> Available
}

Step 3

Extend using the Output interface.

interface ListAndroidOrientations : Output {
    val configPath: String
}

Step 4

Add out implementation to AndroidOrientationsListCommand

class AndroidOrientationsListCommand :
    Runnable,
    ListAndroidOrientations {

    override fun run() = invoke()

    override val out = outputLogger {
        when (this) {
            is Orientation.Available -> list.toCliTable()
            else -> throwUnknownType()
        }
    }
}

Step 5

Replace logLn with out call

operator fun ListAndroidOrientations.invoke() {
    fetchOrientation(
        AndroidArgs.loadOrDefault(Paths.get(configPath)).project,
        Platform.ANDROID
    ).out()
}

Step 6

Consider the proper package for API structures to console output formatters - #1872
If issue #1872 isn't finished yet, place the formatters where you wish. This will be taken into account or refactored further.

Utils

fun outputLogger(map: Any.() -> String): Any.() -> Unit = {
    logLn(map())
}

fun Any.throwUnknownType(): Nothing =
    throw IllegalArgumentException(javaClass.toGenericString())
@jan-goral jan-goral changed the title Design structural output for domain layer Structural output from domain layer Apr 22, 2021
@jan-goral jan-goral changed the title Structural output from domain layer Structural output of domain layer Apr 22, 2021
@jan-goral
Copy link
Contributor Author

The commands grouped difficulty.

Simple

  • DescribeAndroidLocales
  • DescribeAndroidModels
  • DescribeAndroidTestEnvironment
  • DescribeAndroidVersions
  • DescribeIosLocales
  • DescribeIosModels
  • DescribeIosTestEnvironment
  • DescribeIosVersions
  • DescribeNetworkProfiles
  • ListAndroidLocales
  • ListAndroidModels
  • ListAndroidOrientations
  • ListAndroidVersions
  • ListIosLocales
  • ListIosModels
  • ListIosOrientations
  • ListIosVersions
  • ListIPBlocks
  • ListNetworkProfiles
  • ListProvidedSoftware

Average

  • RunDoctorAndroid
  • RunIosDoctor
  • CancelLastRun

Dragon

  • LoginGoogleAccount (passing logs from the client/adapter)
  • RefreshLastRun
  • RunTestAndroid
  • RunIosTest

mergify bot pushed a commit that referenced this issue May 11, 2021
Fixes #1856 

## Test Plan
> How do we know the code works?

* Implementation should follow the specification described in #1728 
* All tests should pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant