From 7b51355e5a621021bd5e5e16b74a575202bb87f5 Mon Sep 17 00:00:00 2001
From: Matt Chernosky <matt@chernosky.net>
Date: Tue, 29 Nov 2016 23:19:52 -0700
Subject: [PATCH 1/2] Module generator finishes for partially existing files

This resolves #219. When generating a new module, if all the files to
generate already exist then it fails as before. If some of the files
already exist, then the files that need to be created are created. Any
existing files are not changed.

Also added a bunch of tests for this feature via rspec. Run them from
the test folder with `rake spec`.
---
 .gitignore                                    |   1 +
 auto/generate_module.rb                       |  16 +-
 test/rakefile                                 |   9 +-
 .../generate_module_existing_file_spec.rb     | 158 ++++++++++++++++++
 4 files changed, 180 insertions(+), 4 deletions(-)
 create mode 100644 test/spec/generate_module_existing_file_spec.rb

diff --git a/.gitignore b/.gitignore
index c4901d0..f0c7c3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 build/
+test/sandbox
 .DS_Store
 examples/example_1/test1.out
 examples/example_1/test2.out
diff --git a/auto/generate_module.rb b/auto/generate_module.rb
index 2ec14c5..0fbaf55 100644
--- a/auto/generate_module.rb
+++ b/auto/generate_module.rb
@@ -187,14 +187,24 @@ class UnityModuleGenerator
 
     files = files_to_operate_on(module_name, pattern)
 
-    #Abort if any module already exists
+    #Abort if all of the module files already exist
+    all_files_exist = true
     files.each do |file|
-      raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path])
+      if not File.exist?(file[:path])
+        all_files_exist = false
+      end
     end
+    raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist
 
     # Create Source Modules
     files.each_with_index do |file, i|
-      FileUtils.mkdir_p(File.dirname(file[:path]), :verbose => false) # Create the path first if necessary.
+      # If this file already exists, don't overwrite it.
+      if File.exist?(file[:path])
+        puts "File #{file[:path]} already exists!"
+        next
+      end
+      # Create the path first if necessary.
+      FileUtils.mkdir_p(File.dirname(file[:path]), :verbose => false)
       File.open(file[:path], 'w') do |f|
         f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil?
         f.write(file[:template] % [ file[:name],
diff --git a/test/rakefile b/test/rakefile
index 5df66fb..000ab00 100644
--- a/test/rakefile
+++ b/test/rakefile
@@ -10,9 +10,11 @@ $verbose = false
 require 'rake'
 require 'rake/clean'
 require UNITY_ROOT + 'rakefile_helper'
+require 'rspec/core/rake_task'
 
 TEMP_DIRS = [
-	File.join(UNITY_ROOT, 'build')
+	File.join(UNITY_ROOT, 'build'),
+	File.join(UNITY_ROOT, 'sandbox')
 ]
 
 TEMP_DIRS.each do |dir|
@@ -40,6 +42,11 @@ task :scripts => [:prepare_for_tests] do
   end
 end
 
+desc "Run all rspecs"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.pattern = 'spec/**/*_spec.rb'
+end
+
 desc "Generate test summary"
 task :summary do
   report_summary
diff --git a/test/spec/generate_module_existing_file_spec.rb b/test/spec/generate_module_existing_file_spec.rb
new file mode 100644
index 0000000..74e7fc8
--- /dev/null
+++ b/test/spec/generate_module_existing_file_spec.rb
@@ -0,0 +1,158 @@
+
+require '../auto/generate_module.rb'
+require 'fileutils'
+
+def touch_src(file)
+  FileUtils.touch "sandbox/src/#{file}"
+end
+
+def touch_test(file)
+  FileUtils.touch "sandbox/test/#{file}"
+end
+
+def create_src_with_known_content(file)
+  File.open("sandbox/src/#{file}", "w") {|f| f.write("the original #{file}")}
+end
+
+def create_test_with_known_content(file)
+  File.open("sandbox/test/#{file}", "w") {|f| f.write("the original #{file}")}
+end
+
+def expect_src_content_didnt_change(file)
+  expect(File.read("sandbox/src/#{file}")).to eq("the original #{file}")
+end
+
+def expect_test_content_didnt_change(file)
+  expect(File.read("sandbox/test/#{file}")).to eq("the original #{file}")
+end
+
+def expect_src_file_to_exist(file)
+  expect(File.exist?("sandbox/src/#{file}")).to be true
+end
+
+def expect_test_file_to_exist(file)
+  expect(File.exist?("sandbox/test/#{file}")).to be true
+end
+
+describe "UnityModuleGenerator" do
+
+  before do
+    # clean sandbox and setup our "project" folders
+    FileUtils.rm_rf "sandbox"
+    FileUtils.mkdir_p "sandbox"
+    FileUtils.mkdir_p "sandbox/src"
+    FileUtils.mkdir_p "sandbox/test"
+
+    @options = {
+      :path_src => "sandbox/src",
+      :path_tst => "sandbox/test",
+    }
+  end
+
+  context "with src pattern" do
+    before do
+      @options[:pattern] = "src"
+    end
+
+    it "fails when all files already exist" do
+      # create an existing triad of files
+      touch_src "meh.c"
+      touch_src "meh.h"
+      touch_test "Testmeh.c"
+      expect {
+        UnityModuleGenerator.new(@options).generate("meh")
+      }.to raise_error("ERROR: File meh already exists. Exiting.")
+    end
+
+    it "creates the test file if the source and header files exist" do
+      # Create the existing files.
+      touch_src "meh.c"
+      touch_src "meh.h"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_test_file_to_exist "Testmeh.c"
+    end
+
+    it "does not alter existing files" do
+      # Create some files with known content.
+      create_src_with_known_content "meh.c"
+      create_src_with_known_content "meh.h"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_src_content_didnt_change "meh.c"
+      expect_src_content_didnt_change "meh.c"
+    end
+
+    it "does not alter existing test files" do
+      # Create some files with known content.
+      create_test_with_known_content "Testmeh.c"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_test_content_didnt_change "Testmeh.c"
+    end
+
+  end
+
+  context "with mch pattern" do
+    before do
+      @options[:pattern] = "mch"
+    end
+
+    it "fails when all files exist" do
+        touch_src "meh_model.c"
+        touch_src "meh_conductor.c"
+        touch_src "meh_hardware.c"
+        touch_src "meh_model.h"
+        touch_src "meh_conductor.h"
+        touch_src "meh_hardware.h"
+        touch_test "Testmeh_model.c"
+        touch_test "Testmeh_conductor.c"
+        touch_test "Testmeh_hardware.c"
+        expect {
+          UnityModuleGenerator.new(@options).generate("meh")
+        }.to raise_error("ERROR: File meh_model already exists. Exiting.")
+    end
+
+    it "creates files that don't exist" do
+      touch_src "meh_model.c"
+      touch_src "meh_conductor.c"
+      touch_src "meh_hardware.c"
+      touch_src "meh_model.h"
+      touch_src "meh_conductor.h"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_src_file_to_exist "meh_hardware.h"
+      expect_test_file_to_exist "Testmeh_model.c"
+      expect_test_file_to_exist "Testmeh_conductor.c"
+      expect_test_file_to_exist "Testmeh_hardware.c"
+    end
+
+    it "does not alter existing source files" do
+      create_src_with_known_content "meh_model.c"
+      create_src_with_known_content "meh_model.c"
+      create_src_with_known_content "meh_model.c"
+      create_src_with_known_content "meh_model.h"
+      create_src_with_known_content "meh_model.c"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_src_content_didnt_change "meh_model.c"
+      expect_src_content_didnt_change "meh_model.c"
+      expect_src_content_didnt_change "meh_model.c"
+      expect_src_content_didnt_change "meh_model.c"
+    end
+
+    it "does not alter existing test files" do
+      create_test_with_known_content "Testmeh_model.c"
+
+      UnityModuleGenerator.new(@options).generate("meh")
+
+      expect_test_content_didnt_change "Testmeh_model.c"
+    end
+
+  end
+end

From df2d37459bc51cdbc7a0352970995be4dff38408 Mon Sep 17 00:00:00 2001
From: Matt Chernosky <matt@chernosky.net>
Date: Fri, 2 Dec 2016 22:57:10 -0700
Subject: [PATCH 2/2] Try manually installing rspec in Travis CI.

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 3b45fd7..c9af107 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,7 @@ matrix:
 
 before_install:
   - if [ "$TRAVIS_OS_NAME" == "osx" ]; then rvm install 2.1 && rvm use 2.1 && ruby -v; fi
+install: gem install rspec
 script:
   - cd test && rake ci
   - make -s