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:
Blake Watters
2011-04-14 21:52:29 -04:00
parent 462cf35be4
commit c7f61fec16
3 changed files with 225 additions and 35 deletions

View File

@@ -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
View 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
View 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.