Code Monkey home page Code Monkey logo

dvr's People

Contributors

armstrongnate avatar ayanonagon avatar danthorpe avatar dasmer avatar dgdosen avatar dmiluski avatar eliperkins avatar florianbuerger avatar hyperspacemark avatar loudmouth avatar m-herold avatar nanoxd avatar sethhoward avatar soffes avatar stephencelis avatar thasspp 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dvr's Issues

Rename start/end recording to begin/finish batch

I was thinking having startRecording/stopRecording in a test is weird since you only record once. Those methods are used for batch requests in one cassette. It would probably be best if these were renamed to beginBatch and finishBatch (or endBatch).

Running tests with DVR crashes Xcode

Seems to be a new issue in 0.2.0. I get either Invalid request. The request was not found in the cassette. or Something has gone horribly wrong. before Xcode hits a breakpoint and promptly crashes.

Add support for download tasks

This will require refactoring a significant amount. Right now most of the recording logic lives in the data task. We'll need to make this more abstract so it can work for both.

We could also make download tasks use data tasks internally and just write it out to a temp file. The consumer won't know the difference.

Ignore BaseURL

When you use sandbox and production services they have different baseURL. I added the possibility to ignore the baseURL when matching url requests. If this is useful i can create a PR from my fork.

Ignore URL's query string when checking for interaction presence.

So this is a bug that has been haunting me for a few weeks now. And was the cause of me not running my service classes' specs unless I wasn't too lazy to recreate the cassettes.

Here's a snippet from my project that creates a get request with query parameters:

if let p = params where method == "GET" {
    let charset = NSCharacterSet.URLQueryAllowedCharacterSet()
    var query = ""
    for key,value in p {
        if let escapedValue = String(p[key]!).stringByAddingPercentEncodingWithAllowedCharacters(charset) {
            query += "\(key)=\(escapedValue)&"
        }
    }
    urlString += "?\(query)"
}
  • param is a [String : AnyObject] dictionary;
  • method is a string defining http verb

So this snippet constructs a query string and appends it to urlString variable that has the base url and resource path combined.

This urlString is then passed to NSURLRequest initializer that creates a request to perform with a session that holds a cassette.

And this is where the trouble comes in. DVR check's for presence of interaction in the cassette by looking at the request's URL. And by definition dictionary does not guarantee the order of the keys in which they will be passed in iteration.

If you have ["foo": 5, "bar" : true] the resulting query string can have two variations:

  • let query1 = "foo=5&bar=true&"
  • let query2 = "bar=true&foo=5&"

In the end they mean the same thing and will be interpreted correctly by the server, but the check will fail since query1 != query2.

I'm not sure how people construct requests in their code, but the solution can be achieved in two ways

  • make sure that query string key-values have deterministic order (e.g. alpahbetically a-z) and construct query string always in the same matter;
  • Add code in DVR interaction's check that ignores the query string when comparing URLs (split by ?) and compare the key values that are stored in the query string (reconstruct the dict by splitting by & and then by =).

If this project is still alive, I'd like to hear anyones thoughts.

Xcode crashes right after new cassette recorded

Both my Xcode's (7.1 and 7.2-beta.3) crash when I run a test that uses DVR where no cassette exists yet. Crash happens right after DVR records the request, logs the fact to console and then aborts to stop running - immediately after or maybe even at the time of the abort there's a crash.

Here's a snippet from the crash log:

Crashed Thread:        38  <DBGLLDBSessionThread (pid=2221)>  Dispatch queue: DVTInvalidationPreventionQueue

DVR is probably not at fault here, but has anyone experienced this and been able to fix or workaround the crash?

Specify a license

I'm adding a podspec for DVR, but it requires a license. I'm assuming MIT, but can you please add it to the repo?

Version 1.3.0 is breaking: cassettes cannot be found

Unfortunately I have not been able to pinpoint the issue yet (I have taken a look at the changes from 1.2.0 to 1.3.0) but I can share that I have a branch where all my tests correctly find the relevant cassettes on version 1.2.0 (and Xcode 9), but with 1.3.0 (and Xcode 10) the tests crash as the cassettes can't be found.

Something about the diff between 1.2.0 and 1.3.0 is causing this change. Any ideas what may be the issue?

If we can't pinpoint the problem, then maybe we should deprecate 1.3.0 and release it as 2.0.0 instead since the changes are seemingly breaking behavior.

Improve README documentation

Right now, our README is fairly sparse. It might be good to pull out some examples from our tests cases and document how DVR can be used in those situations.

Better feedback when a cassette doesn't match

If you specify a cassette, it exists, and doesn't contain the request you specified, it would be really helpful if it said why it thinks the request you specified doesn't match the one in the cassette.

Automatic redacting

I know VCR does this. We should copy them. Manually redacting cassettes is pretty tedious.

Swift Package Manager

I'm writing an API wrapper as a library and just started using DVR in my tests, loving it! I'd really love my library staying compatible with Cocoapods, Carthage and Swift Package Manager. This world of three different package managers to support is really something in this ecosystem ๐Ÿ˜ƒ. My dependencies are declared and integrated via Carthage, which works just fine. Cocoapods doesn't really need to know about DVR since that never runs my tests anyhow. Buuut I kinda still want to be able to run swift test... Is there any way to currently accomplish this?
I don't think SPM supports private/dev/test dependencies, does it? Or would it make sense to include DVR as a normal dependency but only require it in test files? Not sure how Swift handles that...

Nevertheless, support for SPM here would be superb and much appreciated. If it makes sense of course. Thanks! ๐Ÿ˜Š

Not recording any files?

Hey there,

love the idea of the library but I just cannot get it record anything. What am I missing? Tried injecting the session all the way to where it was used which didn't do anything so I took a step back and just tried recording the session directly. Which again didn't do anything:

let session = Session(cassetteName: "example")
let task = session.dataTaskWithURL(NSURL(string: "https://api.dailymotion.com/video/x26m1j4")!) { _, _, _ in
}
task.resume()

Also tried dataTaskWithRequest but same difference. The test always passes.

Looking at the README I would expect it to fail with assert: "โ€ฆ with path of the recorded file. โ€ฆ"

Put together a sample: https://github.com/JanGorman/DVRSample

Fatal error when using DownloadTask when cassette is not available

DownloadTask crashes with message "[DVR] Something has gone horribly wrong." when trying to download a file from a remote location.
I am getting the same message even when i am using the example test for downloadTask.
The url is valid and the file is there because i download with the sharedSession the file from that URL, and it downloads successfully.

Nil interaction.responseData for certain content-types

Just upgraded to DVR v0.1 and migrated my JSON cassettes using the convert.rb script. Tests started failing because I was not getting JSON data (just a response).

I believe the culprit is https://github.com/venmo/DVR/blob/master/DVR/Interaction.swift#L58.

DVR checks for contentType == "application/json", but the Content-Type header field can contain more than that. In my case it is application/json; charset=utf-8.

Was gonna submit a pull request, but the project refuses to run tests for me due to some Xcode 7 beta 5 silliness: seeing dozens of devices in my device list, then when I choose one and try to run tests from test navigator it says the device is not valid for tests. Building for tests leads to symbol not found errors. :\

One more thing: thank you for DVR. Really liking how it makes a whole category of tests in my app feasible. ๐Ÿ’–

Testing api failures

Hi there,
I'm using DVR, and so far I've managed successfully to create tests when api requests return success. But now I want to test the failure of the same requests. So I'm facing a problem when using DVR to test failures (401, 404 etc)..

When run for 2nd time (first time is to record the response), instead of failure callback, success callback is called with the error response inside of it. Any idea why?

Using Alamofire.
Example code (creating and executing any request):

request.validate().responseJSON(completionHandler: {
    response in
    switch response.result {

         case .success(let JSON):
// This is what gets called instead of failure. Response code is 401 and the JSON contains error message.

              callback(true, JSON, nil)

         case .failure(let error):
              if let data = response.data, data.count > 0 {
                  let JSON = try! JSONSerialization.jsonObject(with: data, options: .allowFragments)
                  callback(false, JSON, error as NSError?)
              } else {
                  callback(false, nil, error as NSError?)
              }
     }
}).resume()

Cassette doesn't exist, but library reports the request is not found

I intentionally changed the cassette name when initialising a session, however the test fails with fatalError() call from DVR stating that the request was not found. I am certain the json file is not there and have performed the clean build/test and even removal of DerivedData folder.

[DVR.Session delegate]: unrecognized selector

I'm trying to use a DVR Session with Alamofire but using it to initialize a Manager generates an unrecognized selector exception.

This conversation deals with my use case, but the advice ("Just create a session delegate, then create your custom session, and pass both in.") doesn't seem to work. Since DVR's Session is a subclass of NSURLSession I would expect that you could ask for its delegate but it's breaking for some reason.

let delegate = Manager.SessionDelegate()
let backingSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: delegate, delegateQueue: nil)
let maybeBundle = NSBundle.allBundles().filter{ $0.bundlePath.lowercaseString.containsString("xctest") }.first
if let bundle = maybeBundle {
    let session = Session(outputDirectory: "~/Desktop/DVR/", cassetteName: cassetteName, testBundle: bundle, backingSession: backingSession)
}

Add support for recording multiple network calls in one test run

Since Cassette saves an array of Interactions, instead of just one, it would be great to add support for recording and replaying multiple interactions in one test case.

Possible changes for recording:

  • add a property on Session called recordMultiple, which would allow for not stopping after the first Interaction has been recorded
  • add a method on Session called finishRecording(), which persists all Interactions from memory to disk and asserts to present the file path, like it does now. finishRecording() would only have to be called if recordMultiple is set to true
  • maybe even call finishRecording() from deinit of Session, so that user doesn't have to call it manually

Possible changes for replaying:

  • keep counter of which Interaction should be played next, automatically increment after each replay
  • assert on deinit that exactly the number of prerecorded Interactions has been called (fail the test if more or less network calls were made)

???

Profit.

Xcode 10 build error

Description

Unable to build project in Xcode 11 beta 6.

I receive error Instance method 'filter' is internal and cannot be referenced from a default argument value in Session class init(outputDirectory:cassetteName:testBundle:backingSession:) function.

Screenshots

dvr-filter-compile-error

Environment

  • MacBook Pro 15-inch, 2017, 2.9 Ghz, intel i7, 16 GB
  • macOS High Sierra 10.13.6
  • Xcode 10, beta 6
  • Command Line Tools: Xcode 9.4.1 (9F2000) and 10.0 (10L232m)
  • Swift 4

Reproduction

  1. Open DVR.xcodeproj in Xcode 10, beta 6.
  2. Open file Session.swift, observe error on parameter testBundle.

HTTP status codes not recorded when not 200.

My type used for storing errors returned by my API hold the http status code so that user's can get more information while debugging their failed requests. However, when writing acceptance tests that the correct status codes are returned, DVR simply returns HTTP status code 0 always.

It looks like the status code is not being recorded in the cassette.

Any chance we can also record the status code?

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.