PageRenderTime 37ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/bundle/gems/thor-0.19.1/spec/parser/options_spec.rb

https://gitlab.com/gag2502/EP3OO
Ruby | 414 lines | 356 code | 58 blank | 0 comment | 11 complexity | 914e367050e09d3f5663cb99ee1954bb MD5 | raw file
  1. require "helper"
  2. require "thor/parser"
  3. describe Thor::Options do
  4. def create(opts, defaults = {}, stop_on_unknown = false)
  5. opts.each do |key, value|
  6. opts[key] = Thor::Option.parse(key, value) unless value.is_a?(Thor::Option)
  7. end
  8. @opt = Thor::Options.new(opts, defaults, stop_on_unknown)
  9. end
  10. def parse(*args)
  11. @opt.parse(args.flatten)
  12. end
  13. def check_unknown!
  14. @opt.check_unknown!
  15. end
  16. def remaining
  17. @opt.remaining
  18. end
  19. describe "#to_switches" do
  20. it "turns true values into a flag" do
  21. expect(Thor::Options.to_switches(:color => true)).to eq("--color")
  22. end
  23. it "ignores nil" do
  24. expect(Thor::Options.to_switches(:color => nil)).to eq("")
  25. end
  26. it "ignores false" do
  27. expect(Thor::Options.to_switches(:color => false)).to eq("")
  28. end
  29. it "writes --name value for anything else" do
  30. expect(Thor::Options.to_switches(:format => "specdoc")).to eq('--format "specdoc"')
  31. end
  32. it "joins several values" do
  33. switches = Thor::Options.to_switches(:color => true, :foo => "bar").split(" ").sort
  34. expect(switches).to eq(%w["bar" --color --foo])
  35. end
  36. it "accepts arrays" do
  37. expect(Thor::Options.to_switches(:count => [1, 2, 3])).to eq("--count 1 2 3")
  38. end
  39. it "accepts hashes" do
  40. expect(Thor::Options.to_switches(:count => {:a => :b})).to eq("--count a:b")
  41. end
  42. it "accepts underscored options" do
  43. expect(Thor::Options.to_switches(:under_score_option => "foo bar")).to eq('--under_score_option "foo bar"')
  44. end
  45. end
  46. describe "#parse" do
  47. it "allows multiple aliases for a given switch" do
  48. create %w[--foo --bar --baz] => :string
  49. expect(parse("--foo", "12")["foo"]).to eq("12")
  50. expect(parse("--bar", "12")["foo"]).to eq("12")
  51. expect(parse("--baz", "12")["foo"]).to eq("12")
  52. end
  53. it "allows custom short names" do
  54. create "-f" => :string
  55. expect(parse("-f", "12")).to eq("f" => "12")
  56. end
  57. it "allows custom short-name aliases" do
  58. create %w[--bar -f] => :string
  59. expect(parse("-f", "12")).to eq("bar" => "12")
  60. end
  61. it "accepts conjoined short switches" do
  62. create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => true
  63. opts = parse("-fba")
  64. expect(opts["foo"]).to be true
  65. expect(opts["bar"]).to be true
  66. expect(opts["app"]).to be true
  67. end
  68. it "accepts conjoined short switches with input" do
  69. create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => :required
  70. opts = parse "-fba", "12"
  71. expect(opts["foo"]).to be true
  72. expect(opts["bar"]).to be true
  73. expect(opts["app"]).to eq("12")
  74. end
  75. it "returns the default value if none is provided" do
  76. create :foo => "baz", :bar => :required
  77. expect(parse("--bar", "boom")["foo"]).to eq("baz")
  78. end
  79. it "returns the default value from defaults hash to required arguments" do
  80. create Hash[:bar => :required], Hash[:bar => "baz"]
  81. expect(parse["bar"]).to eq("baz")
  82. end
  83. it "gives higher priority to defaults given in the hash" do
  84. create Hash[:bar => true], Hash[:bar => false]
  85. expect(parse["bar"]).to eq(false)
  86. end
  87. it "raises an error for unknown switches" do
  88. create :foo => "baz", :bar => :required
  89. parse("--bar", "baz", "--baz", "unknown")
  90. expect { check_unknown! }.to raise_error(Thor::UnknownArgumentError, "Unknown switches '--baz'")
  91. end
  92. it "skips leading non-switches" do
  93. create(:foo => "baz")
  94. expect(parse("asdf", "--foo", "bar")).to eq("foo" => "bar")
  95. end
  96. it "correctly recognizes things that look kind of like options, but aren't, as not options" do
  97. create(:foo => "baz")
  98. expect(parse("--asdf---asdf", "baz", "--foo", "--asdf---dsf--asdf")).to eq("foo" => "--asdf---dsf--asdf")
  99. check_unknown!
  100. end
  101. it "accepts underscores in commandline args hash for boolean" do
  102. create :foo_bar => :boolean
  103. expect(parse("--foo_bar")["foo_bar"]).to eq(true)
  104. expect(parse("--no_foo_bar")["foo_bar"]).to eq(false)
  105. end
  106. it "accepts underscores in commandline args hash for strings" do
  107. create :foo_bar => :string, :baz_foo => :string
  108. expect(parse("--foo_bar", "baz")["foo_bar"]).to eq("baz")
  109. expect(parse("--baz_foo", "foo bar")["baz_foo"]).to eq("foo bar")
  110. end
  111. it "interprets everything after -- as args instead of options" do
  112. create(:foo => :string, :bar => :required)
  113. expect(parse(%w[--bar abc moo -- --foo def -a])).to eq("bar" => "abc")
  114. expect(remaining).to eq(%w[moo --foo def -a])
  115. end
  116. it "ignores -- when looking for single option values" do
  117. create(:foo => :string, :bar => :required)
  118. expect(parse(%w[--bar -- --foo def -a])).to eq("bar" => "--foo")
  119. expect(remaining).to eq(%w[def -a])
  120. end
  121. it "ignores -- when looking for array option values" do
  122. create(:foo => :array)
  123. expect(parse(%w[--foo a b -- c d -e])).to eq("foo" => %w[a b c d -e])
  124. expect(remaining).to eq([])
  125. end
  126. it "ignores -- when looking for hash option values" do
  127. create(:foo => :hash)
  128. expect(parse(%w[--foo a:b -- c:d -e])).to eq("foo" => {"a" => "b", "c" => "d"})
  129. expect(remaining).to eq(%w[-e])
  130. end
  131. it "ignores trailing --" do
  132. create(:foo => :string)
  133. expect(parse(%w[--foo --])).to eq("foo" => nil)
  134. expect(remaining).to eq([])
  135. end
  136. describe "with no input" do
  137. it "and no switches returns an empty hash" do
  138. create({})
  139. expect(parse).to eq({})
  140. end
  141. it "and several switches returns an empty hash" do
  142. create "--foo" => :boolean, "--bar" => :string
  143. expect(parse).to eq({})
  144. end
  145. it "and a required switch raises an error" do
  146. create "--foo" => :required
  147. expect { parse }.to raise_error(Thor::RequiredArgumentMissingError, "No value provided for required options '--foo'")
  148. end
  149. end
  150. describe "with one required and one optional switch" do
  151. before do
  152. create "--foo" => :required, "--bar" => :boolean
  153. end
  154. it "raises an error if the required switch has no argument" do
  155. expect { parse("--foo") }.to raise_error(Thor::MalformattedArgumentError)
  156. end
  157. it "raises an error if the required switch isn't given" do
  158. expect { parse("--bar") }.to raise_error(Thor::RequiredArgumentMissingError)
  159. end
  160. it "raises an error if the required switch is set to nil" do
  161. expect { parse("--no-foo") }.to raise_error(Thor::RequiredArgumentMissingError)
  162. end
  163. it "does not raises an error if the required option has a default value" do
  164. options = {:required => true, :type => :string, :default => "baz"}
  165. create :foo => Thor::Option.new("foo", options), :bar => :boolean
  166. expect { parse("--bar") }.not_to raise_error
  167. end
  168. end
  169. context "when stop_on_unknown is true" do
  170. before do
  171. create({:foo => :string, :verbose => :boolean}, {}, true)
  172. end
  173. it "stops parsing on first non-option" do
  174. expect(parse(%w[foo --verbose])).to eq({})
  175. expect(remaining).to eq(%w[foo --verbose])
  176. end
  177. it "stops parsing on unknown option" do
  178. expect(parse(%w[--bar --verbose])).to eq({})
  179. expect(remaining).to eq(%w[--bar --verbose])
  180. end
  181. it "retains -- after it has stopped parsing" do
  182. expect(parse(%w[--bar -- whatever])).to eq({})
  183. expect(remaining).to eq(%w[--bar -- whatever])
  184. end
  185. it "still accepts options that are given before non-options" do
  186. expect(parse(%w[--verbose foo])).to eq("verbose" => true)
  187. expect(remaining).to eq(%w[foo])
  188. end
  189. it "still accepts options that require a value" do
  190. expect(parse(%w[--foo bar baz])).to eq("foo" => "bar")
  191. expect(remaining).to eq(%w[baz])
  192. end
  193. it "still interprets everything after -- as args instead of options" do
  194. expect(parse(%w[-- --verbose])).to eq({})
  195. expect(remaining).to eq(%w[--verbose])
  196. end
  197. end
  198. describe "with :string type" do
  199. before do
  200. create %w[--foo -f] => :required
  201. end
  202. it "accepts a switch <value> assignment" do
  203. expect(parse("--foo", "12")["foo"]).to eq("12")
  204. end
  205. it "accepts a switch=<value> assignment" do
  206. expect(parse("-f=12")["foo"]).to eq("12")
  207. expect(parse("--foo=12")["foo"]).to eq("12")
  208. expect(parse("--foo=bar=baz")["foo"]).to eq("bar=baz")
  209. end
  210. it "must accept underscores switch=value assignment" do
  211. create :foo_bar => :required
  212. expect(parse("--foo_bar=http://example.com/under_score/")["foo_bar"]).to eq("http://example.com/under_score/")
  213. end
  214. it "accepts a --no-switch format" do
  215. create "--foo" => "bar"
  216. expect(parse("--no-foo")["foo"]).to be nil
  217. end
  218. it "does not consume an argument for --no-switch format" do
  219. create "--cheese" => :string
  220. expect(parse("burger", "--no-cheese", "fries")["cheese"]).to be nil
  221. end
  222. it "accepts a --switch format on non required types" do
  223. create "--foo" => :string
  224. expect(parse("--foo")["foo"]).to eq("foo")
  225. end
  226. it "accepts a --switch format on non required types with default values" do
  227. create "--baz" => :string, "--foo" => "bar"
  228. expect(parse("--baz", "bang", "--foo")["foo"]).to eq("bar")
  229. end
  230. it "overwrites earlier values with later values" do
  231. expect(parse("--foo=bar", "--foo", "12")["foo"]).to eq("12")
  232. expect(parse("--foo", "12", "--foo", "13")["foo"]).to eq("13")
  233. end
  234. it "raises error when value isn't in enum" do
  235. enum = %w[apple banana]
  236. create :fruit => Thor::Option.new("fruit", :type => :string, :enum => enum)
  237. expect { parse("--fruit", "orange") }.to raise_error(Thor::MalformattedArgumentError,
  238. "Expected '--fruit' to be one of #{enum.join(', ')}; got orange")
  239. end
  240. end
  241. describe "with :boolean type" do
  242. before do
  243. create "--foo" => false
  244. end
  245. it "accepts --opt assignment" do
  246. expect(parse("--foo")["foo"]).to eq(true)
  247. expect(parse("--foo", "--bar")["foo"]).to eq(true)
  248. end
  249. it "uses the default value if no switch is given" do
  250. expect(parse("")["foo"]).to eq(false)
  251. end
  252. it "accepts --opt=value assignment" do
  253. expect(parse("--foo=true")["foo"]).to eq(true)
  254. expect(parse("--foo=false")["foo"]).to eq(false)
  255. end
  256. it "accepts --[no-]opt variant, setting false for value" do
  257. expect(parse("--no-foo")["foo"]).to eq(false)
  258. end
  259. it "accepts --[skip-]opt variant, setting false for value" do
  260. expect(parse("--skip-foo")["foo"]).to eq(false)
  261. end
  262. it "will prefer 'no-opt' variant over inverting 'opt' if explicitly set" do
  263. create "--no-foo" => true
  264. expect(parse("--no-foo")["no-foo"]).to eq(true)
  265. end
  266. it "will prefer 'skip-opt' variant over inverting 'opt' if explicitly set" do
  267. create "--skip-foo" => true
  268. expect(parse("--skip-foo")["skip-foo"]).to eq(true)
  269. end
  270. it "accepts inputs in the human name format" do
  271. create :foo_bar => :boolean
  272. expect(parse("--foo-bar")["foo_bar"]).to eq(true)
  273. expect(parse("--no-foo-bar")["foo_bar"]).to eq(false)
  274. expect(parse("--skip-foo-bar")["foo_bar"]).to eq(false)
  275. end
  276. it "doesn't eat the next part of the param" do
  277. create :foo => :boolean
  278. expect(parse("--foo", "bar")).to eq("foo" => true)
  279. expect(@opt.remaining).to eq(%w[bar])
  280. end
  281. end
  282. describe "with :hash type" do
  283. before do
  284. create "--attributes" => :hash
  285. end
  286. it "accepts a switch=<value> assignment" do
  287. expect(parse("--attributes=name:string", "age:integer")["attributes"]).to eq("name" => "string", "age" => "integer")
  288. end
  289. it "accepts a switch <value> assignment" do
  290. expect(parse("--attributes", "name:string", "age:integer")["attributes"]).to eq("name" => "string", "age" => "integer")
  291. end
  292. it "must not mix values with other switches" do
  293. expect(parse("--attributes", "name:string", "age:integer", "--baz", "cool")["attributes"]).to eq("name" => "string", "age" => "integer")
  294. end
  295. end
  296. describe "with :array type" do
  297. before do
  298. create "--attributes" => :array
  299. end
  300. it "accepts a switch=<value> assignment" do
  301. expect(parse("--attributes=a", "b", "c")["attributes"]).to eq(%w[a b c])
  302. end
  303. it "accepts a switch <value> assignment" do
  304. expect(parse("--attributes", "a", "b", "c")["attributes"]).to eq(%w[a b c])
  305. end
  306. it "must not mix values with other switches" do
  307. expect(parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"]).to eq(%w[a b c])
  308. end
  309. end
  310. describe "with :numeric type" do
  311. before do
  312. create "n" => :numeric, "m" => 5
  313. end
  314. it "accepts a -nXY assignment" do
  315. expect(parse("-n12")["n"]).to eq(12)
  316. end
  317. it "converts values to numeric types" do
  318. expect(parse("-n", "3", "-m", ".5")).to eq("n" => 3, "m" => 0.5)
  319. end
  320. it "raises error when value isn't numeric" do
  321. expect { parse("-n", "foo") }.to raise_error(Thor::MalformattedArgumentError,
  322. "Expected numeric value for '-n'; got \"foo\"")
  323. end
  324. it "raises error when value isn't in enum" do
  325. enum = [1, 2]
  326. create :limit => Thor::Option.new("limit", :type => :numeric, :enum => enum)
  327. expect { parse("--limit", "3") }.to raise_error(Thor::MalformattedArgumentError,
  328. "Expected '--limit' to be one of #{enum.join(', ')}; got 3")
  329. end
  330. end
  331. end
  332. end