summaryrefslogtreecommitdiffstats
path: root/spec/unit/util/command_line_spec.rb
blob: 6cf90475bbfb63c87f81aefeea7c33c845fcd361 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env ruby

require 'spec_helper'


require 'puppet/util/command_line'

describe Puppet::Util::CommandLine do
  include PuppetSpec::Files
  before do
    @tty  = stub("tty",  :tty? => true )
    @pipe = stub("pipe", :tty? => false)
  end

  it "should pull off the first argument if it looks like a subcommand" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp }, @tty )

    command_line.subcommand_name.should == "client"
    command_line.args.should            == %w{ --help whatever.pp }
  end

  it "should use 'apply' if the first argument looks like a .pp file" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp }, @tty )

    command_line.subcommand_name.should == "apply"
    command_line.args.should            == %w{ whatever.pp }
  end

  it "should use 'apply' if the first argument looks like a .rb file" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb }, @tty )

    command_line.subcommand_name.should == "apply"
    command_line.args.should            == %w{ whatever.rb }
  end

  it "should use 'apply' if the first argument looks like a flag" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug }, @tty )

    command_line.subcommand_name.should == "apply"
    command_line.args.should            == %w{ --debug }
  end

  it "should use 'apply' if the first argument is -" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ - }, @tty )

    command_line.subcommand_name.should == "apply"
    command_line.args.should            == %w{ - }
  end

  it "should return nil if the first argument is --help" do
    command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help }, @tty )

    command_line.subcommand_name.should == nil
  end


  it "should return nil if there are no arguments on a tty" do
    command_line = Puppet::Util::CommandLine.new("puppet", [], @tty )

    command_line.subcommand_name.should == nil
    command_line.args.should            == []
  end

  it "should use 'apply' if there are no arguments on a pipe" do
    command_line = Puppet::Util::CommandLine.new("puppet", [], @pipe )

    command_line.subcommand_name.should == "apply"
    command_line.args.should            == []
  end

  it "should return the executable name if it is not puppet" do
    command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty )

    command_line.subcommand_name.should == "puppetmasterd"
  end

  it "should translate subcommand names into their legacy equivalent" do
    command_line = Puppet::Util::CommandLine.new("puppet", ["master"], @tty)
    command_line.legacy_executable_name.should == "puppetmasterd"
  end

  it "should leave legacy command names alone" do
    command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty)
    command_line.legacy_executable_name.should == "puppetmasterd"
  end

  describe "when the subcommand is not implemented" do
    it "should find and invoke an executable with a hyphenated name" do
      commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
      Puppet::Util.expects(:which).with('puppet-whatever').returns('/dev/null/puppet-whatever')
      commandline.expects(:system).with('/dev/null/puppet-whatever', 'argument')

      commandline.execute
    end

    describe "and an external implementation cannot be found" do
      it "should abort and show the usage message" do
        commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
        Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
        commandline.expects(:system).never

        text = Puppet::Faces[:help, :current].help
        commandline.expects(:puts).with { |x| x =~ /Unknown Puppet subcommand/ }
        commandline.expects(:puts).with text

        commandline.execute
      end
    end
  end
  describe 'when loading commands' do
    before do
      @core_apps = %w{describe filebucket kick queue resource agent cert apply doc master}
      @command_line = Puppet::Util::CommandLine.new("foo", %w{ client --help whatever.pp }, @tty )
    end
    it "should expose available_subcommands as a class method" do
      @core_apps.each do |command|
        @command_line.available_subcommands.should include command
      end
    end
    it 'should be able to find all existing commands' do
      @core_apps.each do |command|
        @command_line.available_subcommands.should include command
      end
    end
    describe 'when multiple paths have applications' do
      before do
        @dir=tmpdir('command_line_plugin_test')
        @appdir="#{@dir}/puppet/application"
        FileUtils.mkdir_p(@appdir)
        FileUtils.touch("#{@appdir}/foo.rb")
        $LOAD_PATH.unshift(@dir) # WARNING: MUST MATCH THE AFTER ACTIONS!
      end
      it 'should be able to find commands from both paths' do
        found = @command_line.available_subcommands
        found.should include 'foo'
        @core_apps.each { |cmd| found.should include cmd }
      end
      after do
        $LOAD_PATH.shift        # WARNING: MUST MATCH THE BEFORE ACTIONS!
      end
    end
  end
end