From c5babe71f0679f09aa83385d6f96036f521dc472 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Tue, 28 Aug 2018 17:18:56 +1000 Subject: [PATCH] feat(stub-server): allow pacts to be loaded from a directory Closes: #94 --- lib/pact/stub_service/cli.rb | 24 ++++++--- lib/pact/support/expand_file_list.rb | 26 +++++++++ .../lib/pact/support/expand_file_list_spec.rb | 54 +++++++++++++++++++ 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 lib/pact/support/expand_file_list.rb create mode 100644 spec/lib/pact/support/expand_file_list_spec.rb diff --git a/lib/pact/stub_service/cli.rb b/lib/pact/stub_service/cli.rb index 9eef1bc..75e63ef 100755 --- a/lib/pact/stub_service/cli.rb +++ b/lib/pact/stub_service/cli.rb @@ -10,16 +10,17 @@ module Pact module StubService class CLI < Pact::MockService::CLI::CustomThor - desc 'PACT_URI ...', "Start a stub service with the given pact file(s)." + desc 'PACT_URI ...', "Start a stub service with the given pact file(s) or directory." long_desc <<-DOC - Start a stub service with the given pact file(s). Pact URIs may be local file paths or HTTP. + Start a stub service with the given pact file(s) or directories. Pact URIs may be local + file or directory paths, or HTTP. Include any basic auth details in the URL using the format https://USERNAME:PASSWORD@URI. Where multiple matching interactions are found, the interactions will be sorted by response status, and the first one will be returned. This may lead to some non-deterministic behaviour. If you are having problems with this, please raise it on the pact-dev google group, and we can discuss some potential enhancements. Note that only versions 1 and 2 of the pact specification are currently fully supported. - Pacts using the v3 format may be used, however, any matching features added in v4 will + Pacts using the v3 format may be used, however, any matching features added in v3 will currently be ignored. DOC @@ -33,13 +34,16 @@ class CLI < Pact::MockService::CLI::CustomThor method_option :stub_pactfile_paths, hide: true method_option :monkeypatch, hide: true - def service(*pactfiles) - raise Thor::Error.new("Please provide an existing pact file to load") if pactfiles.empty? + def service(*pact_files) require 'pact/mock_service/run' - options.stub_pactfile_paths = pactfiles + require 'pact/support/expand_file_list' + + expanded_pact_files = file_list(pact_files) + raise Thor::Error.new("Please provide at least one pact file to load") if expanded_pact_files.empty? + opts = Thor::CoreExt::HashWithIndifferentAccess.new opts.merge!(options) - opts[:stub_pactfile_paths] = pactfiles + opts[:stub_pactfile_paths] = expanded_pact_files opts[:pactfile_write_mode] = 'none' MockService::Run.(opts) end @@ -52,6 +56,12 @@ def version end default_task :service + + no_commands do + def file_list(pact_files) + Pact::Support::ExpandFileList.call(pact_files) + end + end end end end diff --git a/lib/pact/support/expand_file_list.rb b/lib/pact/support/expand_file_list.rb new file mode 100644 index 0000000..c4befae --- /dev/null +++ b/lib/pact/support/expand_file_list.rb @@ -0,0 +1,26 @@ +module Pact + module Support + module ExpandFileList + def self.call pact_files + pact_files + .collect{ |path| unixify_path(path) } + .collect{ | path | expand_path(path) } + .flatten + end + + def self.unixify_path(path) + path.gsub(/\\+/, '/') + end + + def self.expand_path(path) + if File.directory?(path) + Dir.glob(File.join(path, "*.json")) + elsif Dir.glob(path).any? + Dir.glob(path) + else + path + end + end + end + end +end diff --git a/spec/lib/pact/support/expand_file_list_spec.rb b/spec/lib/pact/support/expand_file_list_spec.rb new file mode 100644 index 0000000..58eb276 --- /dev/null +++ b/spec/lib/pact/support/expand_file_list_spec.rb @@ -0,0 +1,54 @@ +require 'pact/support/expand_file_list' + +module Pact + module Support + module ExpandFileList + describe "#call" do + + subject { ExpandFileList.call(file_list) } + + context "with a list of json files" do + let(:file_list) { ["file1.json", "file2.json"] } + + it "returns the list" do + expect(subject).to eq file_list + end + end + + context "with a list of json files that contains a windows path" do + let(:file_list) { ["c:\\foo\\file1.json"] } + + it "returns the list in Unix format" do + expect(subject).to eq ["c:/foo/file1.json"] + end + end + + context "with a directory" do + let(:file_list) { ["spec/support/"] } + + it "returns a list of the json files inside" do + expect(subject.size).to be > 1 + + subject.each do | path | + expect(path).to start_with("spec/support") + expect(path).to end_with(".json") + end + end + end + + context "with a glob" do + let(:file_list) { ["spec/support/*.json"] } + + it "returns a list of the json files inside" do + expect(subject.size).to be > 1 + + subject.each do | path | + expect(path).to start_with("spec/support") + expect(path).to end_with(".json") + end + end + end + end + end + end +end