Unable to create Fragment class in jetpack compose - android-jetpack-compose

class HomeFragment : Fragment() {
override fun <I : Any?, O : Any?> prepareCall(
contract: ActivityResultContract<I, O>,
callback: ActivityResultCallback<O>
): ActivityResultLauncher<I> {
TODO("Not yet implemented")
}
override fun <I : Any?, O : Any?> prepareCall(
contract: ActivityResultContract<I, O>,
registry: ActivityResultRegistry,
callback: ActivityResultCallback<O>
): ActivityResultLauncher<I> {
TODO("Not yet implemented")
}
}
When extent with Fragment it is expect to implement the above overrride method, What needs to return?? When implement compose library in gradle.
Can any one suggest how to set up project for some screen as Composable and some screen as activity and fragment likw.

Update or add your fragment ktx dependency to the latest version:
implementation 'androidx.fragment:fragment-ktx:1.3.0'

Related

How to mock docker ApiClient in Golang?

I've implemented a wrapper for the Docker ApiClient like so
type DockerClient struct {
cli client.APIClient
}
I've also defined my own interface for interacting with Docker like so
type Dockerer interface {
Init() error
CreateContainer(ctx context.Context, imageName string) (string, error)
RunCommand(ctx context.Context, containerId string, command string) (string, int, error)
StopContainer(ctx context.Context, containerId string) error
}
DockerClient implements the functions in the Dockerer interface like so:
func (d *DockerClient) Init() error {
//...
}
func (d *DockerClient) CreateContainer(ctx context.Context, imageName string) (string, error) {
//...
}
func (d *DockerClient) RunCommand(ctx context.Context, containerId string, command string) (string, int, error) {
//...
}
func (d *DockerClient) StopContainer(ctx context.Context, containerId string) error {
//...
}
This has made it easy to test the components of my code that need to interface with Docker because I can generate a mock for my Dockerer interface and dependency inject that mock.
However, now I'd like to write tests for the actual implementation of the DockerClient wrapper. It seems like no mocks are provided for ApiClient by the docker package. Is there a canonical pattern for writing tests when the package I need to use doesn't provide mocks? Is there a way to get mockery to generate mocks for library interfaces?
client.APIClient is an interface. You can embed that interface in a struct. Yes you can do this. You can embed interface inside struct. Then you selectively implement methods that you need for test. This way you don't have to implement every single method from the interface. It will impractical to implement all the methods that client.APIClient provides because it embeds interface that embeds whole lot of interfaces. See.
Like this,
type mockCli struct{
client.APIClient
}
func (mockCli) ClientVersion() string {
return "5"
}
func TestA(t *testing.T) {
dc := &DockerClient{
cli: new(mockCli),
}
...
dc.Init()
// This will print "5" if your Init has
// fmt.Println(d.cli.ClientVersion())) somewhere.
// If you call any other method of cli, you get panic.
// A good thing. It will inform you that you are using
// some method that you don't have on mockCli. You
// just add it then.
}

How do I add a Global Tag in Axe DevTools (Attest)

I'm using Axe DevTools and I'm trying to figure out how to tag multiple scans with the same build information. Right now I have my tests running like this:
class MyTestCase : XCTestCase {
func myTest() {
Attest.that(view: view)
.isAccessible({ result in })
.andPushResult(withTags: [myBuild])
}
}
How can I add the myBuild tag globally to all tests that I run?
I would build my own class that utilizes the Axe DevTools (Attest) APIs. Then have my test cases interact with my own class instead of interacting with Attest itself!
class AccessibilityTestUtils {
static let buildTag:String = Bundle.main.object(
forInfoDictionaryKey: "CFBundleShortVersionString"
) as! String
init(build: String) {
self.buildTag = build
}
static func runAccessibilityTestOn(aView : View) {
Attest.that(view: aView).isAccessible({ result in })
.andPushResult(withTags: [buildTag])
}
}
Example Usage
class YourTestClass {
func yourTestCase() {
AccessibilityTestUtils.runAccessibilityTestOn(aView)
}
}
Note: This approach also protects you from future changes to the Attest library by making it so that you only have to change one line of code in the event of non backwards compatible changes.

Swift, use function UIView.removeFromSuperview as an argument in forEach function over array of views

I would like to change following code
let views: [UIView] = []
views.forEach {
$0.removeFromSuperview()
}
to some other way, in which I pass function UIView.removeFromSuperview as an argument to the forEach function.
Something similar to
let views: [UIView] = []
views.map { /* transform views to be passed further */ }
.forEach(UIView.removeFromSuperview)
Is it possible somehow?
UPDATE
Based on the answer below and some comments, I can sum up feedback for this question for myself a bit.
Instance Methods are “Curried” Functions in Swift (By Ole Begemann)
Flattening the function type of unapplied method references (Swift Evolution)
Based on the latter, Chris Lattner has mentioned some flip function in a paragraph Impact on existing code.
My assumption about its implementation is something following
func flip<T>(_ function: #escaping (T) -> () -> Void) -> (T) -> Void {
return { object in function(object)() }
}
Thus, we can rewrite initial code like
views.forEach(flip(UIView.removeFromSuperview))
It's easy enough to just call the method on $0:
views.forEach {
$0.removeFromSuperview()
}
(And you can name the argument if you like.)
But you could also wrap it into a method:
extension Sequence {
func onEach(_ invoke: (Iterator.Element) -> () -> Void) {
self.forEach { invoke($0)() }
}
}
This works because instance methods can be represented as functions that take an instance of their type and return a function that has their "top-level" signature.
One downside here is that you can't include the rethrows annotation that's present on forEach, because rethrows only applies if the function argument itself is throwing.

How to define of initializing generic type in Swift

I'm writing the function like this
func issueArrayFromResponse(response: DataResponse<Any>) -> Result<[Issue]> {}
However this kind of function appear many time, such as repoArrayFromResponse, gistArrayFromRespnse and so on. So I tried to make these functions into one.
func arrayFromResponse<T>(response: DataResponse<Any>) -> Result<[T]> {}
The problem is I don't have initializer for type T and don't know how to achieve it. In case issueArrayFromResponse, I have a class Issue and it has initializer: init(json: [[String: Any]]), so i was able to write
issue = Issue(json: item)
However, in case arrayFromResponse<T>, the compiler says 'T' cannot be constructed because it has no accessible initializers
How can I make initializer for T?
I think the easiest way is to make protocol.
You can make such protocol:
protocol ResultProtocol {
}
and confirm all your classes to this protocol
class Issue: ResultProtocol {
init(json: String) {
}
}
then you can:
func arrayFromResponse<T: ResultProtocol>(response: DataResponse<Any>) -> Result<[T]> {
return Result<[T]>()
}

Anonymous inner Class in Swift

In Java I can do the following:
interface SomeCallback {
void onDone();
}
then I can create a function like this:
void test(SomeCallback callback) {
...
}
To call this function I do:
test(new SomeCallback() {
#Override
void done() {
...
}
});
I want to do something similar in Swift. I could create a protocol
protocol SomeCallback : class {
func done()
}
and a function like this
func test(callback: SomeCallback) {
...
}
I am still struggling with the call of this function.
Edit: Since I use an external API which requires a delegate I cannot use a Closure.
Is it possible to create some kind of anonymous inner class like I did it in the Java example to call test()?
Update: If you can't use a closure/function, the direct answer is: no, there are no anonymous inner classes. However, as Mike M points out, you'll have to use a class, and this class may be nested/inner to prevent polluting the global namespace. This class may well have a closure for every method it needs to implement and just call through to those closures.
The Swift-y way of doing this as long as you just need one method is to just use a lambda/closure.
For example, see NSComparator, which is typealiased since it is used all over the place and you are meant to recognize it.
In your example, specifying a function type inline will do fine. So for example:
func test(callback: () -> Void) {
...
callback()
}
// called as:
test({ in
...
})
// or even (since it's the last parameter)
test { in
...
}
Just to clarify the syntax because what you wrote is a little confusing.
#objc protocol SomeCallback {
func done() -> Void
}
No need to inherit from class as you wrote. Also, don't forget the #objc even if you do not want to bridge the protocol to that language. It helps with compiler complaints later on (might be a bug at the moment)
You cannot instantiate a protocol in Swift. You can however have an internal class that inherits from NSObject (root object) and implements this.
class External: NSObject {
class Internal : SomeCallback {
func done() {
// does something
}
}
let int = Internal()
func test(callback : SomeCallback) {
// additional work
callback.done()
}
}

Resources