Giter VIP home page Giter VIP logo

swift-custom-dump's Introduction

Swift 5.7 CI @pointfreeco

This repo contains the full source code for the Point-Free website, a video series exploring advanced programming topics in Swift. The codebase is split into 3 pieces:

  • PointFree: This is the core application, and is responsible for routing requests, loading data and rendering HTML and CSS.
  • Styleguide: This library contains functions and data types for creating a consistent style across the entire website.
  • Server: This is the actual executable server. It uses NIO to handle the low-level server responsibilities, and hands everything else over to the PointFree package.

Point-Free Homepage

Getting Started

Interested in a video tour of the code base?

video poster image

The repo contains an extensive test suite and some playgrounds to explore. To get things running:

  • Open up a terminal window and grab the code:

    git clone https://github.com/pointfreeco/pointfreeco.git
    cd pointfreeco
  • Make sure cmark is installed. You can install it with Homebrew:

    brew install cmark # or your preferred installation method
  • Make sure Postgres is installed and running. It's our database of choice. You can install it with Homebrew:

    brew install postgres # or your preferred installation method
    brew services start postgresql # or your preferred launch method
    make db

    (If you use Postgres.app, EnterpriseDB, or another installation method, please follow some additional instructions in the CPostgreSQL README.)

With the project open in Xcode, you can:

  • Run the server locally
    • Select the Server target
    • Run: Command+R
    • Visit http://localhost:8080
  • Explore our playgrounds
    • Select the PointFree target
    • Build: Command+B
    • Open a playground!

Some fun things to explore

There're a lot of fun things to explore in this repo. For example:

  • We develop web pages in playgrounds for a continuous feedback loop. This is made possible by the fact that the entire server stack is composed of pure functions with side-effects pushed to the boundaries of the application. It allows us to load up any request in isolation, including POST requests, all without ever worrying about doing a side-effect. Server side Swift in a playground

  • We use snapshot testing to capture full data structures in order to verify their correctness. Not only do we do this in the traditional way of taking screenshots of web pages at various break points (e.g. on iPhone and desktop), but we can also snapshot any entire request-to-response lifecycle (e.g. the POST to a signup page does the correct redirect).

β–Ώ Step
  ResponseEnded

β–Ώ Request
  POST http://localhost:8080/launch-signup

  [email protected]

β–Ώ Response
  Status 302 FOUND
  Location: /?success=true

Xcode Color Theme

Like the color theme we use in our episodes? Run make colortheme to install locally!

Related projects

Point-Free uses a bunch of interesting open-source software:

  • πŸ—Ί swift-html: A Swift DSL for type-safe, extensible, and transformable HTML documents.
  • πŸ•Έ swift-web: A collection of types and functions for dealing with common web server concerns, such as HTML render, CSS preprocessing, middleware and more.
  • 🎢 swift-prelude: Offers a standard library for experimental functional programming in Swift.
  • 🏷 swift-tagged: Helps us create strong contracts with our data boundaries, like JSON from GitHub and Stripe, and our PostgreSQL data.
  • πŸ“Έ swift-snapshot-testing: Powers our testing infrastructure by taking snapshots of various data structures to guarantee the correctness of their output. We use this on everything from middleware to ensure requests are correctly transformed into responses, and even entire web pages to make sure the site looks correct at a variety of sizes (e.g. on iPhone and desktop).

Explore more of our open-source on the Point-Free organization.

Learn More

Brandon gave a talk about most of the core ideas that went into this project at Swift Summit 2017.

The two sides of writing testable code

Find this interesting?

Then check out Point-Free!

License

The content of this project itself is licensed under the CC BY-NC-SA 4.0 license, and the underlying source code used to format and display that content is licensed under the MIT license.

swift-custom-dump's People

Contributors

aaron-foreflight avatar aroben avatar bellaposa avatar brentleyjones avatar brianmichel avatar davdroman avatar finestructure avatar iampatbrown avatar importryan avatar inamiy avatar jaanussiim avatar jacksonutsch avatar jeehut avatar klundberg avatar konomae avatar larryonoff avatar mbrandonw avatar noppefoxwolf avatar rhysm94 avatar stephencelis avatar tahirmt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-custom-dump's Issues

Some `AttributedString`s don't print any diffs although they are not equal

Describe the bug
Some AttributedStrings don't print any diffs although they are not equal

To Reproduce
CustomDumpAttributedString.zip

// If you’ll run this test:

    func testAttributedString() throws {
        var stringOne = AttributedString("One")
        stringOne.font = .body
        
        var stringTwo = AttributedString("One")
        stringTwo.font = .callout
        
        XCTAssertNoDifference(stringOne, stringTwo)
    }

// It’ll fail, but the printed dump will make it look like there are no differences at all:

XCTAssertNoDifference failed: …

    "One"

(First: βˆ’, Second: +)

// Where if I change the text to be different in addition to the font:

    func testAttributedString() throws {
        var stringOne = AttributedString("One")
        stringOne.font = .body
        
        var stringTwo = AttributedString("Two")
        stringTwo.font = .callout
        
        XCTAssertNoDifference(stringOne, stringTwo)
    }

// it prints it correctly:

XCTAssertNoDifference failed: …

  βˆ’ "One"
  + "Two"

(First: βˆ’, Second: +)

// This problem is especially prominent when the AttributedString is a property of a State object inside of a Store, the test could fail and you’ll have no idea that the AttributedString is the one which is different:

XCTAssertNoDifference failed: …

    State(
      string: "One",
      number: 3
    )

(First: βˆ’, Second: +)

Expected behavior

// In my opinion I would expect at least:

- "One"
+ "One"

Environment

  • swift-custom-dump 1.1.2
  • Xcode 15.0 (15A240d)
  • Swift 5.9
  • OS: iOS 17.0

Nested dictionaries are not sorted when using `customDump(_:to:)`

Describe the bug
When using customDump(_:to:) with a plain dictionary eg [String: Int] the keys are sorted correctly.
When this dictionary is nested, eg in a struct, the keys are no longer sorted.
I noticed this bug when I migrated a project from 0.6.1 to 0.10.2 (seems to occur from 0.10.0 and above).

To Reproduce

import CustomDump
import XCTest

final class DictionarySortedDumpTests: XCTestCase {
    // Works as expected
    func testDictionaryDump() {
        // Given
        let dictionary = ["a": 5, "b": 9, "c": 1, "d": -3, "e": 12]
        let expectedResult = """
[
  "a": 5,
  "b": 9,
  "c": 1,
  "d": -3,
  "e": 12
]
"""
        
        // When
        var buffer = Buffer()
        customDump(dictionary, to: &buffer)
        
        // Then
        XCTAssertEqual(buffer.value, expectedResult)
    }
    
    // Fails for ~(5! - 1) times
    func testNestedDictionaryDump() {
        // Given
        let dictionary = ["a": 5, "b": 9, "c": 1, "d": -3, "e": 12]
        let expectedResult = """
NestedDictionary(
  content: [
    "a": 5,
    "b": 9,
    "c": 1,
    "d": -1,
    "e": 12
  ]
)
"""
        
        // When
        var buffer = Buffer()
        customDump(NestedDictionary(content: dictionary), to: &buffer)
        
        // Then
        XCTAssertEqual(buffer.value, expectedResult)
    }
}

private struct Buffer: TextOutputStream {
    private(set) var value: String = ""
    mutating func write(_ string: String) {
        value += string
    }
}

private struct NestedDictionary {
    private let content: [String: Int]
    
    init(content: [String: Int]) {
        self.content = content
    }
}

Expected behavior
I would expect that nested dictionaries are sorted alphabetically like it was in version 0.9.1 and below.
The consistent output is important when for example using snapshot testing. Now every time we record new snapshots the files change. But also the compare fails.

Screenshots

Environment

  • swift-custom-dump version 0.10.2
  • Xcode 14.2
  • Swift 5
  • OS: iOS 16.0

Additional context

Crash when dumping a key path in release build with Xcode 14

Describe the bug
Dumping a key path crashes CustomDump. But this only happens in release build that builds on Xcode 14.
Our app uses CustomDump to do logging and now it always crashes when there's a BindingAction gets logged.
Tried on Xcode 13.4.1 and there's no problem.

To Reproduce
Just dump any key paths in release build in Xcode 14.
Sample project: https://github.com/jutoart/DumpKeyPath

public struct DumpKeyPath {
  public private(set) var text = "Hello, World!"
  private let keyPath: WritableKeyPath<DumpKeyPath, String> = \.text
  
  public static func main() {
    customDump(testObject.keyPath) // <-- crash here
  }
}

Screenshots

CleanShot 2022-11-07 at 10 10 53@2x

Environment

  • swift-custom-dump 0.6.0
  • Xcode 14.1.0 (tried on Xcode 14.0.1 and it's the same)
  • Swift 5.7

Xcode 13.2 Compile Error

I have a project that depends on swift-composable-architecture which depends on this package. I am using the latest release, v0.30.0.
After updating to Xcode 13.2 and doing a clean build, my project fails to compile.

Please refer to the screenshots for the issue I am seeing.

Screen Shot 2021-12-14 at 12 48 49 AM

Screen Shot 2021-12-14 at 12 48 54 AM

The Package.swift for my project declares:

 platforms: [
    .iOS(.v15)
  ],

So I do not understand why I am encountering this issue.

Crash occurs when diffing two `LocalizedStringKeys` with special interpolations

Describe the bug
Passing a LocalizedStringKey constructed with basic string interpolation works correctly. For example, the following code works as you would expect:

let name = "Dalton"
let control: LocalizedStringKey = "Static string"
let success: LocalizedStringKey = "Hello, \(name)!"

// This prints:
// - "Static string"
// + "Hello, Dalton!"
print(diff(control, success) ?? "No diff")

However, passing a LocalizedStringKey that uses any of the other variations of string interpolation supported by LocalizedStringKey results in a crash:

let control: LocalizedStringKey = "Static string"
let crash1: LocalizedStringKey = "Date: \(Date(), style: .date)"
let crash2: LocalizedStringKey = "Date range: \(Date.distantPast...Date.distantFuture)"
let crash3: LocalizedStringKey = "Time: \(Duration.seconds(10), format: .time(pattern: .minuteSecond))"

print(diff(control, crash1) ?? "No diff") // crash!
print(diff(control, crash2) ?? "No diff") // crash!
print(diff(control, crash3) ?? "No diff") // crash!

The crash (SIGABRT) occurs on this line:

Array(Mirror(reflecting: children[0].value).children)[0].value as! (Any, Formatter?)

The console output:

Could not cast value of type 'SwiftUI.LocalizedStringKey.FormatArgument.Token' (0x1fea477e8) to 'NSFormatter' (0x1fd708ed8).
2023-09-02 19:11:54.584602-0500 dump-bug[32884:11397570] Could not cast value of type 'SwiftUI.LocalizedStringKey.FormatArgument.Token' (0x1fea477e8) to 'NSFormatter' (0x1fd708ed8).

Expected behavior
I expect that the above code would not result in a crash and would instead print an appropriate diff between the provided strings.

Environment

  • swift-custom-dump version: 1.0.0
  • Xcode Version 14.3.1 (14E300c)
  • Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
  • OS: macOS 13.4.1 (c) (22F770820d) and iOS 16.4

Feature Request: CustomDumpReflectable without a Mirror

I really appreciate the pretty printing of customDump(). However I'm having some challenges with using Mirror in some cases and would like to suggest a new API that prints like a displayStyle: .struct but allows me to explicitly override the typeName.

(Please ignore the protocol naming. I'll trust you guys to come up with something suitable)

extension MyType: CustomDumpValueRespresentable {
  var customDumpValue: CustomDumpValue {
    .init(
      typeName: if isButton ? "Button" : "MyType",
      children: [
        "child": child,
        ...
      ]
  }
}

Thanks.

Version 0.4.0 does not compile

CoreImage extensions with availability constraints result in the following error

Protocol 'CustomDumpStringConvertible' requires 'customDumpDescription' to be available in iOS 9.0.0 and newer

NSNumber crashes CustomDump

Dumping a struct with an NSNumber crashes CustomDump. Storing the number as Double fixes the issue for me. The NSNumber is coming out of CoreBluetooh's API so pretty old and low-level.

XCTAssertNoDifference diff doesn't highlight type differences

Describe the bug
When working with two heterogeneous dictionaries of type [AnyHashable, AnyHasable] in order to compare them where one dictionary represents a floating point value using a Float type and the other using Double leads to a very subtle error where the diff presented shows the two comparing fields as different yet show a identical literal representation.

To Reproduce

    func testBug() {

        let values: [AnyHashable: AnyHashable] = [
            "value": Float(29.99)
        ]

        let expected: [AnyHashable: AnyHashable] = [
            "value": 29.99, // Is a Double
        ]

        XCTAssertNoDifference(values, expected)
    }

Expected behavior
I assume due to precision that Float vs Double can't be compared like for like but I would expected XCTAssertNoDifference to maybe show the type information where the two values are literal identical and where the types are different, so something like:

XCTAssertNoDifference failed: …

    [
  βˆ’   "value": 29.99 (Float)
  +   "value": 29.99 (Double)
    ]

(First: βˆ’, Second: +)

I spent hours trying to work out why my two hashable dictionaries that appeared to have identical values were failing and the diff output was confusing things further. It was very subtle that the code under test was using a Float value and my dictionary I wanted to compare against used a Double literal.

Screenshots
Screenshot 2022-05-03 at 10 01 31

Environment

  • swift-custom-dump version 0.2.1
  • Xcode 13.3.1
  • Swift 5.6

Generic type is ignored

Describe the bug
When trying to dump a generic type, the generic information is not included in the dump

To Reproduce

func testGeneric() {
    struct Box<T> {
        let value: T
    }

    let stringBox = Box(value: "test")

    var dump = ""
    customDump(
        stringBox,
        to: &dump
    )
    XCTAssertNoDifference(
        dump,
    """
    DumpTests.Box(value: \"test\")
    """
    )
    // Expecting the dump to be DumpTests.Box<String>(value: \"test\") instead
}

Expected behavior
Expecting the generic type information to be included in the dump i.e. DumpTests.Box<String>(value: \"test\")

Environment

  • swift-custom-dump version [e.g. 0.6.0]
  • Xcode [e.g. 13.4.1]
  • Swift [e.g. 5.6]
  • OS: [e.g. macOS 12.6]

Allow customization of floating-point precision for XCTAssertNoDifference

Describe the bug
Sometimes, you have a big struct full of floating-point numbers, and you want to test them. But the code that produces these structs is susceptible to the foibles of floating-point math, so you want to use the equivalent of the XCTAssertEqual overload that takes an accuracy parameter. This would let you assert on a whole struct or nested tree of structs, where any floating-point properties are compared with the given accuracy.

To Reproduce

Proposed syntax:

struct MyThing: Equatable {
    var foo: Double
}

let a = MyThing(foo: 1)
let b = MyThing(foo: 1.0001)

XCTAssertNoDifference(a, b, accuracy: 0.01)

Expected behavior
This code compiles, and any floating-point values found in the structs or their children are compared using the given precision.

Additional context

An alternative (that I'm going to use in my app for now) is to write a property wrapper such that you can do:

@CloseEnough var foo: Double

And then have a global/Current-style precision value that you can set before you write an assertion. The @CloseEnough property wrapper would use default == comparison in production, and use the precision value only when running in tests.

I tried adding my proposed fix to swift-custom-dump, but got bogged down in _openExistential soup that I didn't understand enough to proceed.

No diff when comparing two instances of `UIImage` or `#imageLiteral` using `XCTAssertNoDifference `

Describe the bug

When comparing instances of UIImage or #imageLiteral XCTAssertNoDifference doesn't provide a diff, XCTAssertEqual does.

To Reproduce
testExample in ImageResourceComparisonDemoTests has some assertions which show the difference
ImageResourceComparisonDemo.zip

XCTAssertEqual(
    #imageLiteral(
        resourceName: "ExampleImage"
    ),
    #imageLiteral(
        resourceName: "ExampleImage2"
    )
)

// πŸ‘† Produces this diff:

/**
testExample(): XCTAssertEqual failed: ("<UIImage:0x600002d50480 named(main: ExampleImage) {1200, 1200} renderingMode=automatic(original)>") is not equal to ("<UIImage:0x600002d505a0 named(main: ExampleImage2) {1200, 1200} renderingMode=automatic(original)>")
*/

XCTAssertNoDifference(
    #imageLiteral(
        resourceName: "ExampleImage"
    ),
    #imageLiteral(
        resourceName: "ExampleImage2"
    )
)

// πŸ‘† Produces this diff:

/**
testExample(): XCTAssertNoDifference failed: …

  βˆ’ UIImage()
  + UIImage()

(First: βˆ’, Second: +)
*/

Expected behavior
I'd have expected XCTAssertNoDifference to give me an indication of what the difference between the two images is, similar to what XCTAssertEqual does.

Environment

  • swift-custom-dump version [0.6.1]
  • Xcode [14.0.1]
  • Swift [5.7]
  • OS: [iOS 16.0]

Add the ability to dump properties from superclass

Currently customDump only dumps properties from the main mirror. This is missing all the properties from the superclass e.g

class Human {
    let name = "John"
    let email = "[email protected]"
    let age = 97
}

class Doctor: Human {
    let field = "Podiatry"
}

customDump(Doctor())

This prints Doctor(field: "Podiatry")

It would be nice if it could print this instead

Doctor(
  field: "Podiatry",
  name: "John",
  email: "[email protected]"
  age: 97
)

Custom Dump Error on Xcode 13.2 RC

Screenshot 2021-12-08 at 14 31 07

Getting the above error when trying to build a project. Project targets iOS 14.

Not sure if this is a known issue or not.

Appreciate your help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.