Tokamak/Sources/TokamakStaticHTMLBenchmark
Max Desiatov 5926e9f182
Replace `ViewDeferredToRenderer`, fix renderer tests (#408)
This allows writing tests for `TokamakStaticHTML`, `TokamakDOM`, and `TokamakGTK` targets.

The issue was caused by conflicting `ViewDeferredToRenderer` conformances declared in different modules, including the `TokamakTestRenderer` module. 

This works around a general limitation in Swift, which was [discussed at length on Swift Forums previously](https://forums.swift.org/t/an-implementation-model-for-rational-protocol-conformance-behavior/37171). When multiple conflicting conformances to the same protocol (`ViewDeferredToRenderer` in our case) exist in different modules, only one of them is available in a given binary (even a test binary). Also, only of them can be loaded and used. Which one exactly is loaded can't be known at compile-time, which is hard to debug and leads to breaking tests that cover code in different renderers. We had to disable `TokamakStaticHTMLTests` for this reason.

The workaround is to declare two new functions in the `Renderer` protocol:

```swift
public protocol Renderer: AnyObject {
  // ...
  // Functions unrelated to the issue at hand skipped for brevity.

  /** Returns a body of a given pritimive view, or `nil` if `view` is not a primitive view for
   this renderer.
   */
  func body(for view: Any) -> AnyView?

  /** Returns `true` if a given view type is a primitive view that should be deferred to this
   renderer.
   */
  func isPrimitiveView(_ type: Any.Type) -> Bool
}
```

Now each renderer can declare their own protocols for their primitive views, i.e. `HTMLPrimitive`, `DOMPrimitive`, `GTKPrimitive` etc, delegating to them from the implementations of `body(for view:)` and `isPrimitiveView(_:)`. Conformances to these protocols can't conflict across different modules. Also, these protocols can have `internal` visibility, as opposed to `ViewDeferredToRenderer`, which had to be declared as `public` in `TokamakCore` to be visible in renderer modules.
2021-06-07 17:24:02 +01:00
..
main.swift Replace `ViewDeferredToRenderer`, fix renderer tests (#408) 2021-06-07 17:24:02 +01:00