Code Monkey home page Code Monkey logo

Comments (11)

milosmns avatar milosmns commented on May 12, 2024 1

Well... I tried, and it doesn't work. I'll explain in detail, but basically, I believe that it all comes down to Apple's marketing strategy about Swift being an open-source cross-platform language.
A short disclaimer: I just recently started using Swift, and I think the language is ok. It has a bit of that Apple taste, stripping down and removing some necessary constructs... but fine. It just feels like Apple promises/proclaims more about their products than they really are (surprise).

To start, Foundation for Linux seems years away from being complete if they continue development at this pace. Take a look here - https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Status.md#implementation-status - a lot of stuff is not done, and the main Swift feature list just keeps growing. That's just one of the issues.

Having worked on many platforms in the past and using many different languages, I find Swift's support for multi-platform to be the worst, by far. Tooling for build and test actions is completely different on Linux vs. Mac, especially the stuff around running tests. Windows (the world's largest desktop platform) is not even supported... so, for example, Linux requires a file called LinuxMain.swift for each test group. This file specifies which files and tests should be executed during testing on Linux. It's super strange... no other mainstream language requires such a configuration. Fine, never mind, let's continue. There are some workarounds for that problem.

If you run swift test --generate-linuxmain, then the tooling should generate LinuxMain.swift files for you. Only, it doesn't work for Cuckoo for some reason, there's no git diff afterwards. And even if it did work, it requires a Mac machine with all XCode stuff installed to be able to run the command. I tried manually adding those files, but no luck there either, still fails with LinuxMain.swift missing.

Reading through these possible solutions, I found a very interesting solution using flags. Of course, it's not the default behavior, but it kind of works: swift test --enable-index-store --enable-test-discovery. From what I understood, it reads through the test files and generates a .build/ index that swift test command will use to discover tests.

OK, so, we're getting somewhere. This last command runs the tests, but the tests fail. To build Cuckoo, I added the same two flags, and it looks like it builds correctly (release & development variants). Here I don't understand why it builds when the tests are failing with compile errors...

Anyway, I prepared a Dockerfile which you can use to test on your machine. It should be super easy to configure:

  1. Install Docker
  2. Clone this repository
  3. In the repository root add the Dockerfile from below. File name should be just Dockerfile
FROM milosmns/swift-vapor:5.2-bionic
# My base Ubuntu 18.04 image contains Swift 5.2 and server-side framework Vapor on top. I use it for my projects so I am 100% sure that Swift will work inside of it.

# Copy project files to /app
WORKDIR /app
COPY . .

# If Environment becomes necessary, this fixes the issue:
# ARG env
# ENV ENVIRONMENT=$env

# Build and test the project
RUN apt-get update \
    && mkdir -p /build/lib \
    && cp -R /usr/lib/swift/linux/*.so* /build/lib \
    && swift build --enable-index-store --enable-test-discovery --verbose \
    && swift build -c release --enable-index-store --enable-test-discovery --verbose \
    && swift test --enable-index-store --enable-test-discovery
  1. From your Terminal, go to the repo root, run docker build .

One last observation: testing fails with compile errors around UITextView, WebKit and some other non-platform stuff. I'd say that this is related somehow to iOS or Mac development, and not essential... but I have limited experience with these platforms, so I'm just guessing.

If these tests are the only thing that's preventing us from using Cuckoo on other platforms Linux, then I'd argue that these tests and possibly their source and main functionality should be moved to an add-on project, or another "optional" layer somehow. This way we could be able to include the 'core' on both Linux and Mac, and people who develop for iOS/Mac only can include this optional mocking layer on top of 'core'.

@MatyasKriz Let me know what you think. I know I just dumped loads of info here, but I hope it will be helpful for you as you're familiar with the codebase. 😄

from cuckoo.

MatyasKriz avatar MatyasKriz commented on May 12, 2024 1

Hey, @milosmns! That's a very nicely detailed intro to testing Cuckoo on Linux. I'm grateful for your efforts as well as preparing the Dockerfile. I'll take a look at this in more depth as soon as I can.

Just skimming through the code, WebKit is only used in ObjectiveProtocolTest.swift which tests Cuckoo+OCMock functionality and the compiler directive #if os(iOS) should prevent that test suite from being ran.

However, I noticed just recently that I've forgotten to hide import WebKit behind this directive, so that might be one problem. As for the UITextField, I'm not sure why it's failing, that one is correctly enveloped in the compiler directive as far as I can tell.

Though, if there's no other way, we can just remove all the Cuckoo+OCMock tests in the RUN section of the Dockerfile before testing.

Thank you again for the detailed report and your efforts to run the tests! As mentioned, I'll jump into it when I can, probably within a week. Thanks to your research, it should be a breeze for me.

from cuckoo.

MatyasKriz avatar MatyasKriz commented on May 12, 2024 1

Alright, first of all, thanks again for the Dockerfile, sure helps having that prepared and just focusing on the Cuckoo side of things.

I've managed to get Cuckoo compilable as well as getting the tests to run.

SPOILERS The tests pass!

However, it's not really viable for the moment as it requires MockManager to inherit from NSObject for who knows what reason.

Then it requires removing all the OCMock tests, ObjCProtocol tests as well as the checks for correctly excluded classes.

I've switched the image to use the official swift:5.2.2 in hopes that it might fix the NSObject thing, but it didn't and I can't seem to find the source of the issue.

So, to successfully build and test Cuckoo on Linux, this Dockerfile based on @milosmns's one might be used:

FROM swift:5.2.2

# Copy project files to /app
WORKDIR /app
COPY . .

# If Environment becomes necessary, this fixes the issue:
# ARG env
# ENV ENVIRONMENT=$env

# Build and test the project
RUN apt-get update \
    && mkdir -p /build/lib \
    && cp -R /usr/lib/swift/linux/*.so* /build/lib \
    && rm -rf Tests/Swift/OCMock Tests/Swift/Source/ObjcProtocol.swift Tests/Swift/ExcludedStubTest.swift \
    && sed -i 's/class MockManager {/class MockManager: NSObject {/g' Source/MockManager.swift \
    && swift build --enable-index-store --enable-test-discovery \
    && swift build -c release --enable-index-store --enable-test-discovery \
    && swift test --enable-index-store --enable-test-discovery

Maybe I should mention that I'm building this on the latest branch feature/tuist.

It is fragile of course (and I've made the sed more restrictive, so it depends on MockManager being a class and not inheriting or conforming to anything). I don't really mind excluding the ObjC tests, but I don't really like the need to inherit from NSObject just for the sake of it, so I might try looking for a better solution if there is one.

I'd be happy if you looked into the matter as well if you have a hunch. Even if we can't solve this for now, the research and work you've done here will help future pioneers use Cuckoo on Linux. Thanks for that!

from cuckoo.

lvdstam avatar lvdstam commented on May 12, 2024

Is there anybody interested? How would you go about it?

from cuckoo.

TadeasKriz avatar TadeasKriz commented on May 12, 2024

I think this is blocked by supporting Swift Package Manager. I'm not sure how would one go about using Cuckoo on Linux since there is no CocoaPods. This is something we'd like to add in the future.

from cuckoo.

kainjow avatar kainjow commented on May 12, 2024

It appear using Swift PM is the way to do it on Linux. Also makes it easier for projects on the Mac to use without relying on CocoaPods (which has its issues).

from cuckoo.

MatyasKriz avatar MatyasKriz commented on May 12, 2024

We've added SwiftPM in 1.3.2, but I'm not sure if Linux has all the necessary things to fully support mocking with Cuckoo. I don't have any Linux on hand, so I'd be happy if someone tried this.

from cuckoo.

milosmns avatar milosmns commented on May 12, 2024

@MatyasKriz Is it enough to try to build Cuckoo on Linux? If so, a Docker build should provide a proof of that, I have a Swift project that builds that way

from cuckoo.

MatyasKriz avatar MatyasKriz commented on May 12, 2024

@milosmns I am unfortunately completely out of my comfort zone here. I've never tried using Linux for developing anything in Swift and I'm not sure how I'd even go about compiling the project as a whole.
Would you try compiling Cuckoo and perhaps try to make some adjustments that might make it compilable if it's not? In case it's something more serious, we can discuss the next steps here.

from cuckoo.

milosmns avatar milosmns commented on May 12, 2024

Awesome, glad I could be of some help. Hopefully, the Foundation will progress on Linux as well so that we can have a truly cross-platform experience with Swift.

from cuckoo.

milosmns avatar milosmns commented on May 12, 2024

from cuckoo.

Related Issues (20)

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.