Conventions for project organization?

Hi folks,

I’m going to writing a short blog entry for the O’Reilly blog about
ruby conventions for project layout. I think this is relatively
valuable, as it greatly simplifies the ability to audit projects and
possibly contribute to them.

(I’ve been researching a lot of different projects for various
things in Ruport lately)

I think I pretty much follow good practices when it comes to my
project organization, but I’d like to hear what people think and also
if they have anything to add.

Here are a few of the things I think are relevant:

== Structure ==

bin/ : any scripts or executables

lib/ : source files.

conventionally,

Ruport::Data::Table is in

lib/ruport/data/table.rb

alternatively, the class could be included in any file lower down the
chain:
(e.g. lib/ruport.rb or lib/ruport/data.rb)

ext/ : C sources for extensions

doc/: documentation

test/: All tests and test data. Tests should begin with
test_class_name, however an older convention is tc_class_name with
ts_all.rb loading all your tests.

main directory:
Rakefile, main documentation files such as README

== Library requires ==

Do these in the correct logical places, so if you hav

lib/
ruport.rb
ruport/
data.rb
data/
table.rb
record.rb

Then ruport.rb should include:

require “ruport/data”

and data.rb should include:

require “ruport/data/table”
require “ruport/data/record”

There are of course exceptions to this…

== Tests ==

One test per method, ideally, mapping method name to test.
Additional tests for bug reports, edge cases, etc.
( I usually use a name like test_ensure_table_append_accepts_arrays)

or some really long name describing the problem I’m checking for

== Organization of methods in source / tests ==

This i’m not sure about. Some people do alphabetical, some do
alphabetical by concept, some do just concept, some no organization.
I think that it is helpful when the tests follow in the same order of
the source, though.

What do people think about this.

== Other things? ==

I am aiming for something short and simple. I don’t want to overwhelm
people with a ton of rules to follow, but a few basic conventions for
those who haven’t really looked into other projects yet would be
helpful for all of us, I think.

However, if anyone thinks they’ve got some really important tips to
share, let me know.

On Jan 19, 2007, at 2:24 PM, Gregory B. wrote:

lib/ : source files.

Probably want a better explanation there.

test/: All tests and test data. Tests should begin with
test_class_name, however an older convention is tc_class_name with
ts_all.rb loading all your tests.

Rails uses class_name_test.rb which is a little nicer for auto-
completion of the file name.

I guess I’m old-school though because I like tc_* and ts_. To be
clear on that convention, tc_
is for test case files and ts_* is for
test suite files. You can have as many test suites as you want, not
just the top-level ts_all.rb.

James Edward G. II

On 1/19/07, James Edward G. II [email protected] wrote:

I guess I’m old-school though because I like tc_* and ts_. To be
clear on that convention, tc_
is for test case files and ts_* is for
test suite files. You can have as many test suites as you want, not
just the top-level ts_all.rb.

Right, that’s a good point. Often i’ve organized code so that ts_all
calls a number of suites, and those suites call their respective test
cases. I will mention this when I get around to writing this
article.

The only problem i see with tc_* is that I don’t think it works with
autotest, which is a bummer.

On 1/20/07, Suraj K. [email protected] wrote:

the source, though.

These patterns seem to have less effect on BDD (with rSpec), where there
is not such a strong correlation as “one test per method”. Instead, I
think that rSpec encourages organization of both (1) source code and (2)
verification code in terms of “concepts” (as you said).

I am more comfortable with rSpec and its organization by “concept” than
xUnit and the “tests follow in the same order of the source” as you
said.

This is good advice, especially for use with rspec. I’m mostly
interested in (for this particular article) standard ruby however,
since this is the likely target for the community at large.

I’ll keep this in mind though, thanks!

Gregory B. wrote:

lib/ruport/data/table.rb
test_class_name, however an older convention is tc_class_name with
ts_all.rb loading all your tests.

main directory:
Rakefile, main documentation files such as README

It may be a bad habit I’ve picked up from Rails, but for a lot of my
apps (typically small, sqlite-backed XMLRPC services) I also have

db/: Database storage (should be in var/, I know, but what the hell) and
migrations

tmp/: Temporary file storage.

conf/: Configuration files. Usually config/config.default.yaml in svn,
and the app looks for config/config.yaml (which is ignored by svn).

Also, if it’s appropriate, I use lib/models and lib/controllers the same
way Rails uses app/models and app/controllers.

This has been steadily evolving over the past couple of months, and the
logical conclusion will probably be something which looks an awful lot
like Rails, but without the view side or needing to bother with the HTTP
handling.

There are of course exceptions to this…

== Tests ==

One test per method, ideally, mapping method name to test.
Additional tests for bug reports, edge cases, etc.
( I usually use a name like test_ensure_table_append_accepts_arrays)

or some really long name describing the problem I’m checking for
If the app is small enough, I go for test_models.rb,
test_controllers.rb, test_xmlrpc.rb, and controller_test_modules.rb.
test_controllers.rb and test_xmlrpc.rb have test cases which mix in the
same modules from controller_test_modules.rb, the difference being that
the tests in test_xmlrpc.rb actually fire up the executables in bin/ and
perform the tests over XMLRPC to the localhost interface.

Of course, these are things that are quite specific to my niche, but
they may be useful.

Gregory B. wrote:

One test per method, ideally, mapping method name to test.

[…]

== Organization of methods in source / tests ==

This i’m not sure about. Some people do alphabetical, some do
alphabetical by concept, some do just concept, some no organization.
I think that it is helpful when the tests follow in the same order of
the source, though.

These patterns seem to have less effect on BDD (with rSpec), where there
is not such a strong correlation as “one test per method”. Instead, I
think that rSpec encourages organization of both (1) source code and (2)
verification code in terms of “concepts” (as you said).

I am more comfortable with rSpec and its organization by “concept” than
xUnit and the “tests follow in the same order of the source” as you
said.

On Jan 19, 2007, at 20:27, Gregory B. wrote:

article.
I never organize into “suites”. All my tests are capable of running
independently as autotest intended.

The only problem i see with tc_* is that I don’t think it works with
autotest, which is a bummer.

Or testrb. test/test_*.rb is the Test::Unit way.


Eric H. - [email protected] - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!

On 1/20/07, Eric H. [email protected] wrote:

cases. I will mention this when I get around to writing this
article.

I never organize into “suites”. All my tests are capable of running
independently as autotest intended.

Yeah, this is the case for me too since I use autotest. However, Eric
is there any good reason why autotest can’t look up ‘tc_’ as well?
This would probably save some folks some (minor) headaches along the
way. It’s not a big deal, but it seems to me like the test detection
pattern choice should be easy enough to change. Can you use your
config file to do this?

On 1/20/07, Gregory B. [email protected] wrote:

calls a number of suites, and those suites call their respective test
pattern choice should be easy enough to change. Can you use your
config file to do this?

By the way, if it wasn’t clear, in some of my projects I use the ts_*
to organize various test/test_* files.