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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
require "helper"
describe Thor::Group do
describe "command" do
it "allows to use private methods from parent class as commands" do
expect(ChildGroup.start).to eq(%w[bar foo baz])
expect(ChildGroup.new.baz("bar")).to eq("bar")
end
end
describe "#start" do
it "invokes all the commands under the Thor group" do
expect(MyCounter.start(%w[1 2 --third 3])).to eq([1, 2, 3, nil, nil, nil])
end
it "uses argument's default value" do
expect(MyCounter.start(%w[1 --third 3])).to eq([1, 2, 3, nil, nil, nil])
end
it "invokes all the commands in the Thor group and its parents" do
expect(BrokenCounter.start(%w[1 2 --third 3])).to eq([nil, 2, 3, false, 5, nil])
end
it "raises an error if a required argument is added after a non-required" do
expect do
MyCounter.argument(:foo, :type => :string)
end.to raise_error(ArgumentError, 'You cannot have "foo" as required argument after the non-required argument "second".')
end
it "raises when an exception happens within the command call" do
expect { BrokenCounter.start(%w[1 2 --fail]) }.to raise_error
end
it "raises an error when a Thor group command expects arguments" do
expect { WhinyGenerator.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
end
it "invokes help message if any of the shortcuts are given" do
expect(MyCounter).to receive(:help)
MyCounter.start(%w[-h])
end
end
describe "#desc" do
it "sets the description for a given class" do
expect(MyCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
end
it "can be inherited" do
expect(BrokenCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
end
it "can be nil" do
expect(WhinyGenerator.desc).to be nil
end
end
describe "#help" do
before do
@content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
end
it "provides usage information" do
expect(@content).to match(/my_counter N \[N\]/)
end
it "shows description" do
expect(@content).to match(/Description:/)
expect(@content).to match(/This generator runs three commands: one, two and three./)
end
it "shows options information" do
expect(@content).to match(/Options/)
expect(@content).to match(/\[\-\-third=THREE\]/)
end
end
describe "#invoke" do
before do
@content = capture(:stdout) { E.start }
end
it "allows to invoke a class from the class binding" do
expect(@content).to match(/1\n2\n3\n4\n5\n/)
end
it "shows invocation information to the user" do
expect(@content).to match(/invoke Defined/)
end
it "uses padding on status generated by the invoked class" do
expect(@content).to match(/finished counting/)
end
it "allows invocation to be configured with blocks" do
capture(:stdout) do
expect(F.start).to eq(["Valim, Jose"])
end
end
it "shows invoked options on help" do
content = capture(:stdout) { E.help(Thor::Base.shell.new) }
expect(content).to match(/Defined options:/)
expect(content).to match(/\[--unused\]/)
expect(content).to match(/# This option has no use/)
end
end
describe "#invoke_from_option" do
describe "with default type" do
before do
@content = capture(:stdout) { G.start }
end
it "allows to invoke a class from the class binding by a default option" do
expect(@content).to match(/1\n2\n3\n4\n5\n/)
end
it "does not invoke if the option is nil" do
expect(capture(:stdout) { G.start(%w[--skip-invoked]) }).not_to match(/invoke/)
end
it "prints a message if invocation cannot be found" do
content = capture(:stdout) { G.start(%w[--invoked unknown]) }
expect(content).to match(/error unknown \[not found\]/)
end
it "allows to invoke a class from the class binding by the given option" do
error = nil
content = capture(:stdout) do
error = capture(:stderr) do
G.start(%w[--invoked e])
end
end
expect(content).to match(/invoke e/)
expect(error).to match(/ERROR: "thor two" was called with arguments/)
end
it "shows invocation information to the user" do
expect(@content).to match(/invoke defined/)
end
it "uses padding on status generated by the invoked class" do
expect(@content).to match(/finished counting/)
end
it "shows invoked options on help" do
content = capture(:stdout) { G.help(Thor::Base.shell.new) }
expect(content).to match(/defined options:/)
expect(content).to match(/\[--unused\]/)
expect(content).to match(/# This option has no use/)
end
end
describe "with boolean type" do
before do
@content = capture(:stdout) { H.start }
end
it "allows to invoke a class from the class binding by a default option" do
expect(@content).to match(/1\n2\n3\n4\n5\n/)
end
it "does not invoke if the option is false" do
expect(capture(:stdout) { H.start(%w[--no-defined]) }).not_to match(/invoke/)
end
it "shows invocation information to the user" do
expect(@content).to match(/invoke defined/)
end
it "uses padding on status generated by the invoked class" do
expect(@content).to match(/finished counting/)
end
it "shows invoked options on help" do
content = capture(:stdout) { H.help(Thor::Base.shell.new) }
expect(content).to match(/defined options:/)
expect(content).to match(/\[--unused\]/)
expect(content).to match(/# This option has no use/)
end
end
end
describe "edge-cases" do
it "can handle boolean options followed by arguments" do
klass = Class.new(Thor::Group) do
desc "say hi to name"
argument :name, :type => :string
class_option :loud, :type => :boolean
def hi
name.upcase! if options[:loud]
"Hi #{name}"
end
end
expect(klass.start(%w[jose])).to eq(["Hi jose"])
expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"])
expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"])
end
it "provides extra args as `args`" do
klass = Class.new(Thor::Group) do
desc "say hi to name"
argument :name, :type => :string
class_option :loud, :type => :boolean
def hi
name.upcase! if options[:loud]
out = "Hi #{name}"
out << ": " << args.join(", ") unless args.empty?
out
end
end
expect(klass.start(%w[jose])).to eq(["Hi jose"])
expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"])
expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"])
end
end
end
|