jrburke/r.js — pull request #99 by fluidsonic (2012-02-14 01:30:14+00:00)
Title: Config values leak into buildBaseConfig

I'm currently trying to write tests for the `paths` config property. Some of the tests use invalid paths in build configs and then assert a specific exception. But even if I catch the exception and flush the context using `require._buildReset()`, r.js keeps referencing the invalid path entry in all other tests!

Digging a bit through the code, I found the reason for that: Some values from custom config objects leak into the global `buildBaseConfig` configuration.

When loading a configuration in r.js, the following things happen:

1. An empty `config = {}` will be created.
2. `mixin` of `buildBaseConfig` into `config`
3. `mixin` of the given configuration into `config`
4. `mixConfig` of main config file into `config` (if set)
5. `mixConfig` of build config file into `config`

In step 1, `paths` and other object properties of `buildBaseConfig` are merged into the new config object. `paths` and other properties are passed by reference and are not copied. Thus, the `paths` property of the new config points to the same object as the `paths` property of `buildBaseConfig`.

In steps 3 and 4, `paths` of the new config are merged with `paths` from main/build config. Since the new config and `buildBaseConfig` share the same `paths` object, the global `buildBaseConfig` was altered too!

These commits change two things:

* Add a more recent implementation of `lang.mixin` (taken again from Dojo while maintaining backward compatibility for r.js). The old method didn't check for built-in object properties and the newer one is also easier to use.
* Change the function `mixConfig` to not alter objects like `paths`, but to create a new object with the previous value and the new value merged into it.