Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 744587)
+++ test/Makefile.am	(working copy)
@@ -10,12 +10,20 @@
 ## License for the specific language governing permissions and limitations
 ## under the License.
 
-dist_TESTS = runner.sh
+# dist_TESTS = runner.sh
+# 
+# CLEANFILES = runner.beam test.ini
+# 
+# EXTRA_DIST = \
+#     couch_config_test.erl \
+#     couch_config_writer_test.erl \
+#     runner.erl \
+#     test.js
 
-CLEANFILES = runner.beam test.ini
-
-EXTRA_DIST = \
-    couch_config_test.erl \
-    couch_config_writer_test.erl \
-    runner.erl \
-    test.js
+test:
+	rm -f ../src/couchdb/*.beam
+	cd ../ && TEST=EUNIT_TESTS make -j2 all && cd test
+	$(ERLC) -o ../src/couchdb/tests/ ../src/couchdb/tests/*.erl
+	erl -noshell -pa ../src/couchdb/ -pa ../src/couchdb/tests/ \
+	-eval "eunit:test([couch_config, couch_config_writer])" \
+	-s init stop
\ No newline at end of file
Index: src/couchdb/tests/couch_config_writer_tests.erl
===================================================================
--- src/couchdb/tests/couch_config_writer_tests.erl	(revision 0)
+++ src/couchdb/tests/couch_config_writer_tests.erl	(revision 0)
@@ -0,0 +1,185 @@
+% couch_config_writer module test suote
+
+-module(couch_config_writer_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+test_helper(Contents, Expect, Config) when not is_list(Config) ->
+    test_helper(Contents, Expect, [Config]);
+test_helper(Contents, Expect, Config) ->
+    Filename = "local.ini",
+    file:write_file(Filename, Contents),
+
+    % call replace function
+    [couch_config_writer:save_to_file(ConfigVar, Filename) || ConfigVar <- Config],
+    
+    % compare new file with expected file
+    {ok, Result_} = file:read_file(Filename),
+    Result = binary_to_list(Result_),
+
+    % clean up
+    file:delete(Filename),
+    
+    ?assertEqual(Result, Expect).
+
+
+% test functions
+should_replace_existing_variable_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+
+[another section]
+another_var = another_value
+",
+
+    Expect = "[section]
+variable = new_value
+
+[another section]
+another_var = another_value
+",
+    test_helper(Contents, Expect, {{"section", "variable"}, "new_value"}).
+
+should_replace_existing_variable2_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+variable2 = value2
+variable3 = value3
+variable4 = value4
+
+[another_section]
+another_var = another_value
+",
+
+    Expect = "[section]
+variable = value
+variable2 = value2
+variable3 = new_value3
+variable4 = value4
+
+[another_section]
+another_var = another_value
+",
+    test_helper(Contents, Expect, {{"section", "variable3"}, "new_value3"}).
+
+should_replace_existing_variable3_test() ->
+    % create file
+    Contents = "[first_section]
+var=val
+
+[section]
+variable = value
+variable2 = value2
+variable3 = value3
+variable4 = value4
+
+[another_section]
+another_var = another_value
+",
+
+    Expect = "[first_section]
+var=val
+
+[section]
+variable = value
+variable2 = value2
+variable3 = new_value3
+variable4 = value4
+
+[another_section]
+another_var = another_value
+",
+    test_helper(Contents, Expect, {{"section", "variable3"}, "new_value3"}).
+
+should_append_new_variable_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+variable2 = value
+
+[another_section]
+another_var = another_value
+",
+
+    Expect = "[section]
+variable = value
+variable2 = value
+
+fantasy_variable = Citation Needed
+
+[another_section]
+another_var = another_value
+",
+    test_helper(Contents, Expect, {{"section", "fantasy_variable"}, "Citation Needed"}).
+
+
+should_append_new_module_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+",
+
+    Expect = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+
+[one_more_section]
+favourite_food = cupcakes
+",
+    test_helper(Contents, Expect, [{{"one_more_section", "favourite_food"}, "cupcakes"}]).
+
+should_overwrite_variable_further_down_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+",
+
+    Expect = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+
+[erlang]
+option = value
+
+option2 = value2
+",
+    test_helper(Contents, Expect, [{{"erlang", "option"}, "value"}, {{"erlang", "option2"}, "value2"}]).
+
+should_not_append_new_section_twice_test() ->
+    % create file
+    Contents = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+
+[erlang]
+option = value
+
+option2 = value2
+",
+
+    Expect = "[section]
+variable = value
+
+[another_section]
+another_var = another_value
+
+[erlang]
+option = value
+
+option2 = value2
+",
+    test_helper(Contents, Expect, [{{"another_section", "another_var"}, "another_value"}]).
Index: src/couchdb/tests/couch_config_writer_tests.beam
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: src/couchdb/tests/couch_config_writer_tests.beam
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: src/couchdb/tests/couch_config_tests.erl
===================================================================
--- src/couchdb/tests/couch_config_tests.erl	(revision 0)
+++ src/couchdb/tests/couch_config_tests.erl	(revision 0)
@@ -0,0 +1,24 @@
+-module(couch_config_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+should_store_strings_test() ->
+    Filename = "test.ini",
+    file:write_file(Filename, ""),
+
+    Key = "foo",
+    Value = "bar",
+
+    {ok, Proc} = couch_config:start_link([Filename]),
+
+    couch_config:set("test_module", Key, Value),
+    Result = couch_config:get("test_module", Key),
+    couch_config:delete("test_module", Key),
+
+    exit(Proc, kill),
+    receive {'EXIT', Proc, _} -> ok end,
+    
+    % clean up
+    file:delete(Filename),
+
+    ?assertEqual(Value, Result).
Index: src/couchdb/tests/couch_config_tests.beam
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: src/couchdb/tests/couch_config_tests.beam
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: src/couchdb/couch_config_writer.erl
===================================================================
--- src/couchdb/couch_config_writer.erl	(revision 744587)
+++ src/couchdb/couch_config_writer.erl	(working copy)
@@ -21,6 +21,11 @@
 -module(couch_config_writer).
 -include("couch_db.hrl").
 
+-ifdef(TEST).
+  -include_lib("eunit/include/eunit.hrl").
+-endif.
+
+
 -export([save_to_file/2]).
 
 %% @spec save_to_file(
Index: src/couchdb/couch_config.erl
===================================================================
--- src/couchdb/couch_config.erl	(revision 744587)
+++ src/couchdb/couch_config.erl	(working copy)
@@ -19,6 +19,10 @@
 -module(couch_config).
 -include("couch_db.hrl").
 
+-ifdef(TEST).
+  -include_lib("eunit/include/eunit.hrl").
+-endif.
+
 -behaviour(gen_server).
 -export([start_link/1, init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).
Index: src/couchdb/Makefile.am
===================================================================
--- src/couchdb/Makefile.am	(revision 744587)
+++ src/couchdb/Makefile.am	(working copy)
@@ -150,8 +150,11 @@
 # $(ERL) -noshell -run edoc_run files [\"$<\"]
 
 %.beam: %.erl couch_db.hrl
-	$(ERLC) $<
-
+	if test -n "${TEST}"; then \
+	  $(ERLC) -DTEST $<; \
+	else \
+	  $(ERLC) $<; \
+	fi
 install-data-hook:
 	if test -f "$(DESTDIR)/$(couchprivlibdir)/couch_erl_driver"; then \
 	    rm -f "$(DESTDIR)/$(couchprivlibdir)/couch_erl_driver.so"; \

