mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-29 13:15:34 +08:00
Improved the documentation while working on documentation infrastructure: refs #48
* Improved and generalized the documentation about the testing environment. * Added documentation about how to write documentation.
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
RestKit Spec Environment
|
||||
========================
|
||||
|
||||
RestKit ships with a testing infrastructure built around UISpec and
|
||||
an associated Ruby Gem called UISpecRunner. To be able to run the
|
||||
tests, you need to do a little bit of setup:
|
||||
|
||||
1. Initialize the UISpec submodule: `git submodule init && git submodule update`
|
||||
1. Install the Ruby Bundler Gem (if necessary): `sudo gem install bundler`
|
||||
1. Install the other required Gems via Bundler: `bundle`
|
||||
1. Verify the configuration by running the specs: `uispec -v`
|
||||
|
||||
If the project builds the UISpec target correctly and executes the suite, then
|
||||
you are all set. If there are any issues, you may need to reach out to the mailing
|
||||
list for help debugging.
|
||||
|
||||
Once your spec environment has been configured and set up, you can run the entire suite
|
||||
by executing `rake` or `uispec`.
|
||||
|
||||
Running Specs
|
||||
-------------
|
||||
|
||||
UISpecRunner is both a library and a general purpose CLI runner. The library works
|
||||
by plugging into the application and executing specs as configured by some environment
|
||||
variables.
|
||||
|
||||
You can use the `uispec` executable to target and run specific specs or grouping of specs
|
||||
(i.e. unit, functional, integration):
|
||||
|
||||
* Run all specs: `uispec`
|
||||
* Run a specific spec class: `uispec -s RKClientSpec`
|
||||
* Run a specific spec example: `uispec -s RKClientSpec -e itShouldDetectNetworkStatusWithAHostname`
|
||||
* Run all specs conforming to a protocol: `uispec -p UISpecUnit`
|
||||
|
||||
Common spec groupings (i.e. Units and Integration) are configured for execution via the Rakefile.
|
||||
112
Docs/TESTING.md
Normal file
112
Docs/TESTING.md
Normal file
@@ -0,0 +1,112 @@
|
||||
RestKit Spec Environment
|
||||
========================
|
||||
|
||||
RestKit ships with a testing infrastructure built around UISpec and
|
||||
an associated Ruby Gem called UISpecRunner. To be able to run the
|
||||
tests, you need to do a little bit of setup:
|
||||
|
||||
1. Initialize the UISpec submodule: `git submodule init && git submodule update`
|
||||
1. Install the Ruby Bundler Gem (if necessary): `sudo gem install bundler`
|
||||
1. Install the other required Gems via Bundler: `bundle`
|
||||
1. Start the spec server: `rake uispec:server`
|
||||
1. Verify the configuration by running the specs: `uispec -v`
|
||||
|
||||
If the project builds the UISpec target correctly and executes the suite, then
|
||||
you are all set. If there are any issues, you may need to reach out to the mailing
|
||||
list for help debugging.
|
||||
|
||||
Once your spec environment has been configured and set up, you can run the entire suite
|
||||
by executing `rake` or `uispec`.
|
||||
|
||||
Running Specs
|
||||
-------------
|
||||
|
||||
UISpecRunner is both a library and a general purpose CLI runner. The library works
|
||||
by plugging into the application and executing specs as configured by some environment
|
||||
variables.
|
||||
|
||||
You can use the `uispec` executable to target and run specific specs or grouping of specs
|
||||
(i.e. unit, functional, integration):
|
||||
|
||||
* Run all specs: `uispec`
|
||||
* Run a specific spec class: `uispec -s RKClientSpec`
|
||||
* Run a specific spec example: `uispec -s RKClientSpec -e itShouldDetectNetworkStatusWithAHostname`
|
||||
* Run all specs conforming to a protocol: `uispec -p UISpecUnit`
|
||||
|
||||
Common spec groupings (i.e. Units and Integration) are configured for execution via the Rakefile. Execute
|
||||
`rake -T` for a full listing of the pre-configured spec groups available.
|
||||
|
||||
Writing Specs
|
||||
-------------
|
||||
|
||||
RestKit specs are divided into two portions. There are pure unit tests, which only require the test harness to be
|
||||
configured and there are integration tests that test the full request/response life-cycle. In general, testing RestKit is very straight-forward. There are only a few items to keep in mind:
|
||||
|
||||
1. Specs are implemented in Objective-C and run inside the Simulator or on the Device.
|
||||
1. Spec files live in sub-directories under Specs/ appropriate to the layer the code under test belongs to
|
||||
1. UISpec executes Specs via categories. Adding the `UISpec` category to your spec class definition will cause it to be picked up and executed.
|
||||
1. Specs begin with "it" and should be camel-cased descriptive. i.e. itShouldConsiderA200ResponseSuccessful
|
||||
1. UISpec expectations are implemented via the `expectThat` macro:
|
||||
|
||||
[expectThat([someObject someMethod]) should:be(YES)];
|
||||
There is a corresponding `shouldNot` method available as well.
|
||||
1. The RKSpecEnvironment.h header includes a number of helpers.
|
||||
1. OCMock is available for mock objects support. See [http://www.mulle-kybernetik.com/software/OCMock/](http://www.mulle-kybernetik.com/software/OCMock/) for details
|
||||
|
||||
### Writing Integration Tests
|
||||
|
||||
RestKit ships with a Sinatra powered specs server for testing portions of the codebase that require interaction
|
||||
with a web service. Sinatra is a simple Ruby DSL for defining web server. See the [Sinatra homepage](http://www.sinatrarb.com/) for more details.
|
||||
|
||||
The specs server is built as a set of modular Sinatra application in the Specs/Server subdirectory of the RestKit
|
||||
distribution. When you are adding new integration test coverage to the library, you will need to create a new Sinatra application
|
||||
to serve your needs. By convention, these are namespaced by functional unit for simplicity. For example, if we are adding a new
|
||||
cacheing component to the application and want to test the functionality, we would:
|
||||
|
||||
1. Create a new file at `Server/lib/restkit/network/cacheing.rb`
|
||||
1. Create a namespaced Ruby class inheriting from Sinatra::Base to suit our purposes:
|
||||
|
||||
module RestKit
|
||||
module Network
|
||||
class Cacheing < Sinatra::Base
|
||||
get '/cacheing/index' do
|
||||
"OK"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
1. Open restkit.rb and add a require for the cacheing server:
|
||||
|
||||
require 'restkit/network/cacheing'
|
||||
1. Open server.rb and add a use directive to the main spec server to import our module:
|
||||
|
||||
class RestKit::SpecServer < Sinatra::Base
|
||||
self.app_file = __FILE__
|
||||
use RestKit::Network::Authentication
|
||||
use RestKit::Network::Cacheing
|
||||
|
||||
You now have a functional server-side component to work with. Consult the Sinatra documentation for example on setting
|
||||
response headers, MIME types, etc. It's all very simple and low ceremony.
|
||||
|
||||
You can now switch to the RestKit sources and look the in Specs directory. Keeping with the cacheing example, we would create a new RKCacheingSpec.m file and pull in RKSpecEnvironment.h. From there we can utilize `RKSpecResponseLoader` to asynchronously test
|
||||
the entire request/response cycle. The response loader essentially spins the run-loop to allow background processing to execute and
|
||||
simulate a blocking API. The response, objects, or errors generated by processing the response are made available via properties
|
||||
on the RKSpecResponseLoader object.
|
||||
|
||||
Let's take a look at an example of how to use the response loader to test some functionality:
|
||||
|
||||
- (void)itShouldFailAuthenticationWithInvalidCredentialsForHTTPAuthBasic {
|
||||
RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader];
|
||||
RKClient* client = [RKClient clientWithBaseURL:RKSpecGetBaseURL()];
|
||||
client.username = RKAuthenticationSpecUsername;
|
||||
client.password = @"INVALID";
|
||||
[client get:@"/authentication/basic" delegate:loader];
|
||||
[loader waitForResponse];
|
||||
[expectThat([loader.response isOK]) should:be(NO)];
|
||||
[expectThat([loader.response statusCode]) should:be(0)];
|
||||
[expectThat([loader.failureError code]) should:be(NSURLErrorUserCancelledAuthentication)];
|
||||
}
|
||||
|
||||
That's really all there is to it. Consult the existing test code in Specs/ for reference.
|
||||
|
||||
Happy Testing!
|
||||
113
Docs/WRITING_DOCS.md
Normal file
113
Docs/WRITING_DOCS.md
Normal file
@@ -0,0 +1,113 @@
|
||||
Writing Documentation
|
||||
=====================
|
||||
|
||||
RestKit utilizes the excellent [Appledoc](http://www.gentlebytes.com/home/appledocapp/) utility from [Gentle Bytes](http://www.gentlebytes.com/).
|
||||
Appledoc provides a commandline utility for parsing and generating documentation from Objective-C code in HTML and DocSet format. This HTML can be
|
||||
published to the Web and installed directly within Xcode.
|
||||
|
||||
To generate meaningful and informative documentation, Appledoc needs support in the form of markup within the header files. This document
|
||||
seeks to outline the process for marking up RestKit headers to generate great end-user documentation directly from the source code.
|
||||
|
||||
## Generating Documentation
|
||||
|
||||
RestKit ships with a set of Rake tasks that simplify the task of generating documentation. A compiled x86_64 executable of the Appledoc
|
||||
utility is provided with the RestKit distribution at the Vendor/appledoc path. Most authors will not need to interact directly with
|
||||
Appledoc since the process has been automated.
|
||||
|
||||
The tasks available for working with Appledoc are:
|
||||
|
||||
1. `rake docs:generate` - Generates a set of HTML documentation in Docs/API/html
|
||||
1. `rake docs:check` - Runs the RestKit sources through the parser to detect any issues preventing documentation generation
|
||||
1. `rake docs:install` - Generates and installs an Xcode DocSet viewable through the Xcode organizer and integrated help viewer
|
||||
|
||||
## Writing Documentation
|
||||
|
||||
Writing documentation in Appledoc markup is simple. There is extensive documentation available on the [Appledoc project page](http://tomaz.github.com/appledoc/comments.html), but
|
||||
the guidelines below should be sufficient for basic authoring tasks. For clarity, let's consider the following example class:
|
||||
|
||||
/**
|
||||
* Demonstrates how to document a RestKit class using Appledoc
|
||||
*
|
||||
* This class provides a simple boilerplate example for how to properly document
|
||||
* RestKit classes using the Appledoc system. This paragraph forms the details
|
||||
* description of the class and will be presented in detail
|
||||
@interface RKDocumentationExample : NSObject {
|
||||
NSString* _name;
|
||||
NSString* _rank;
|
||||
NSString* _serialNumber;
|
||||
}
|
||||
|
||||
/// @name Demonstrates Documentation Task Groups
|
||||
|
||||
/**
|
||||
* Returns the name of the person in this documentation example
|
||||
*
|
||||
* This property is *important* and that's why the preceeding text will be bolded
|
||||
*/
|
||||
@property (nonatomic, retain) NSString* name;
|
||||
|
||||
/**
|
||||
* The rank of this example in the theoretical documentation hierarchy
|
||||
*
|
||||
* This one is _somewhat important_, so we emphasized that text
|
||||
*
|
||||
* Can be one of the following unordered lists:
|
||||
* - Captain
|
||||
* - General
|
||||
* - Private
|
||||
*/
|
||||
@property (nonatomic, retain) NSString* rank;
|
||||
|
||||
/**
|
||||
* Serial number for this example, as issued by the Colonial Fleet of the 12 Colonies of Kobol
|
||||
*
|
||||
* @warning Somebody might be a Cylon
|
||||
@ @see RKDocumentationSerialNumberGenerator
|
||||
*/
|
||||
@property (nonatomic, retain) NSString* serialNumber;
|
||||
|
||||
/**
|
||||
* Promotes the example to the rank specified
|
||||
*
|
||||
* For example: `[exampleObject promoteToRank:@"General"];`
|
||||
*
|
||||
* @bug This might be broken
|
||||
* @param rank The rank to promote the example to
|
||||
*/
|
||||
- (void)promoteToRank:(NSString*)rank;
|
||||
|
||||
/**
|
||||
* Returns the next rank for this example.
|
||||
*
|
||||
* @return The next rank this example could be promoted to
|
||||
* @exception RKInvalidRankException Raised when there is no current rank
|
||||
*/
|
||||
- (NSString*)nextRank;
|
||||
|
||||
@end
|
||||
|
||||
1. Documentation blocks must precede the item being documented and begin with a slash and a double star. They must be terminated with a single star and a slash.
|
||||
1. The first paragraph forms the short description of the entity being documented.
|
||||
1. The second paragraph forms the long description of the entity and can contain an arbitrary number of paragraphs.
|
||||
1. Methods & properties can be grouped together by using the @name directive. The directive must follow 3 delimiting characters. RestKit standard is '///'
|
||||
1. Text can be bolded and italicized using Markdown standard (i.e. *bolded* and _italicized_)
|
||||
1. Markdown text such as unordered and ordered lists and links can be embedded into the descriptions as appropriate.
|
||||
1. @warning and @bug can be used to call out specific warnings and known issues in the codebase
|
||||
1. Code spans can be embedded by using backticks
|
||||
1. Method arguments should be documented clearly using "@param <param name> Brief description here"
|
||||
1. Method return values should be documented using "@return A description of the return value"
|
||||
1. Exceptions should be documented using "@exception <exception type> Description of the exception raised"
|
||||
1. Cross references to other parts of the codebase can be generated via "@see SomeOtherClass" or "@see [SomeClass someMethod:withArguments:]"
|
||||
|
||||
## Submitting Documentation
|
||||
|
||||
If you want to contribute documentation, the process is simple:
|
||||
|
||||
1. Fork the codebase from the current development branch
|
||||
1. Generate a set of docs to work with via `rake docs` and open `Docs/API/html/index.html` in your browser
|
||||
1. Edit the headers in Code/ and regenerate the docs via `rake docs`
|
||||
1. Repeat the editing and reload cycle until your are happy.
|
||||
1. Commit the code and push to Github
|
||||
1. Submit a Pull Request to the Two Toasters branch on Github at: https://github.com/twotoasters/RestKit/pull/new/master
|
||||
|
||||
You may want to coordinate your efforts via the mailing list to ensure nobody else is working on documentation in the same place.
|
||||
Reference in New Issue
Block a user