#
# Author:: Marc Pardise (<marc@chef.io>)
# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "chef/knife"

Chef::Knife.subcommand_loader.load_commands
commands = Chef::Knife::SubcommandLoader.generate_hash["_autogenerated_command_paths"]["plugins_paths"].keys

# Directly execute each support knife command
context "Command Sanity Check: executing ", :workstation do
  describe "bundle exec knife" do
    commands.each do |command|
      command_name = command.gsub("_", " ")
      modified_command, expected_result = case command_name
                                          when /knife/
                                            # because rspec is the actual executable running, the option parser error message
                                            # is invalid from within the test.
                                            next
                                          when /config (use|get|list) profile.*/
                                            # hyphenated special cases
                                            [command_name, /^USAGE: knife config #{$1}-profile.*/]
                                          when /(role|node|env) (env )?run list(.*)/
                                            # underscored special cases...
                                            env_part = $2.nil? ? "" : "env_"
                                            ["#{$1} #{$2}run_list#{$3}", /^USAGE: knife #{$1} #{env_part}run_list#{$3}.*/]
                                          else
                                            [ command_name, /^USAGE: knife #{command_name}.*/]
                                          end

      # By using bundle exec knife instead of directly loading the command class or using the knife() helper,
      # we ensure that this is a valid end-to-end test.  This operates on the assumption
      # that we continue to require the command class to be fully loaded so that it can handle the parsing of
      # its own options.
      full_command = "#{modified_command} --invalid-option outputs usage for '#{modified_command}' to stdout"
      it full_command do
        result = `bundle exec knife #{full_command}`
        expect(result).to match(expected_result)
      end
    end
  end
end
