#summary Code Conventions for MbUnit These are some simple rules to keep in mind so that we can all play nicely together. Thanks for your consideration and attention to detail. -- Jeff Brown. == Code Style == * Above all else, try to make the code look consistent! Though it is the product of a community of developers, it should feel like it was written by a single (very smart and omniscient) developer. Inconsistencies in style make it more difficult for newcomers to contribute to the project and produces endless arguments and irritation. Inconsistent style just looks sloppy. So keep it beautiful. * For the most part, just follow the Microsoft "Design Guidelines for Developing Class Libraries" (in MSDN) especially the "Guidelines for Names" section. Before you start writing code, please read a bit of it to get a feel for the common style being used by everyone else. Additional notes: * Do not prefix private member names in any way. * Use camel-case for all identifiers including constants. * Capitalize type, method, property and constant names. * No Hungarian notation. * Curly braces on their own lines. * Do not write control structures such as "if" statements all on one line. * Place all field declarations at the top of the class rather than interspersed with with the properties or at the end. Seeing these declarations up-front provides powerful hints that are useful for reading the rest of the code. * Avoid unnecessary field initialization with zeros or nulls. * Place local variable declarations closest to their usage and preferably at their point of initialization. Do not unnecessarily clump them together at the beginning of the function (as when writing code in C style). * Put each type into its own file. This includes enumerations and delegates. They're a lot easier to find that way. The filesystem is your friend. When in doubt, imitate the style predominantly used by the rest of the code. * TABs vs Spaces. I don't care as long as the indentation is equivalent to 4 spaces. Most code editors assume 4 spaces to a tab by default so it looks fine anywhere no matter what. So there! ;-) * Please use liberal vertical whitespace to make reading the code easier. It's astonishingly helpful to have long functions broken down into a series of phases like: validation, processing, and production of the final result. * Highlight broken, incomplete, tricky, or interesting bits in comments. The following standard prefixes are recommended: * // FIXME: * // TODO: * // NOTE: == Documentation == * Apply clear XML documentation comments to all public and protected types and members in the MbUnit.Core and MbUnit.Framework namespaces clearly. Choosing good identifiers is also important. These types and members are public API and we will generate HTML and CHM documentation from them for consumption by testers, developers and system integrators. Use and liberally to cross-reference related concerns. Use ... liberally to document exceptions that may reasonably be thrown by a method. Do not leave empty XML documentation comments. Strip them out if you don't plan to fill them in immediately. That way we can use the compiler so find any missing bits by looking for CS1591 warnings. == Localization == * All localizable strings in each Gallio assembly should be moved to resource files. For non-UI projects, this resource file is called "Resources.resx" and lives in the Properties folder (and namespace) of the assembly (per Visual Studio defaults). Resource strings should be named according to the following pattern based on where they are used: "_". The should be the unqualified type name of the place where the resource string is used. The should be a short descriptive phrase about the content of the resource string, such as the first few words it contains. Strings that are not to be localized should use the verbatim literal syntax with the '@' prefix (like @"foo") to help distinguish them from other strings when doing code sweeps. Please use the automatically generated typesafe accessors to refer to resources whenever possible: they are more robust during refactoring. Tip: The RGreatEx plugin for Resharper greatly simplifies moving strings into resource files. It can be configured to automatically generate resource keys according to our convention. Likewise it can be configured to suppress suggested string to resource refactorings when the string is expressed using the verbatim syntax. Using this tool (or something similar) is strongly recommended. Caveat: RGreatEx can insert custom #pragma's to mark strings not easily represented using '@'. Do not use this feature. The non-standard pragmas generate compiler warnings and may confuse the uninitiated. Instead I've mailed a suggestion to the RGreatEx team to support marking non-externalizable strings with // $NON-NLS-x$ style comments much like the Eclipse NLS tool. == Defensive Coding == * Lightly validate all arguments in API functions. Generally this amounts to checking for nulls and basic bounds. Don't bother validating deep structural integrity rules unless the API function constitutes a real security hazard. Just use the following pattern for checks at the beginning of each function: {{{ if (argument == null) throw new ArgumentNullException("argument"); }}} Please don't invent lots of new helpers for checking nullity: they are slower than inline code, less intuitive, lead to a proliferation of everyone's favority utility functions, and don't benefit from special support offered by refactoring tools like Resharper or checking by FxCop. == Unit Tests == * Use a consistent naming policy for all unit tests. If the class under test is MbUnit.Core.Blah.Foo, then the tests should be in MbUnit.Core.Tests.Blah.FooTest. Integration tests are exempt from this rule because they involve many interacting components. Not all unit tests will have a single class under test. In these cases, use good judgement in arranging the tests so that it is still relatively straightforward to locate them. == License Boilerplate == * All code files (except possibly designer generated code) begin with the Gallio license boilerplate exactly as contained in the CSLicenseBoilerplate.txt file. This boilerplate can be added automatically with the ApplyBoilerplace.bat script.