File: util_spec.rb

package info (click to toggle)
ruby-thor 0.19.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 792 kB
  • ctags: 564
  • sloc: ruby: 7,315; makefile: 2; sh: 1
file content (196 lines) | stat: -rw-r--r-- 7,243 bytes parent folder | download | duplicates (2)
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
require "helper"

module Thor::Util
  def self.clear_user_home!
    @@user_home = nil
  end
end

describe Thor::Util do
  describe "#find_by_namespace" do
    it "returns 'default' if no namespace is given" do
      expect(Thor::Util.find_by_namespace("")).to eq(Scripts::MyDefaults)
    end

    it "adds 'default' if namespace starts with :" do
      expect(Thor::Util.find_by_namespace(":child")).to eq(Scripts::ChildDefault)
    end

    it "returns nil if the namespace can't be found" do
      expect(Thor::Util.find_by_namespace("thor:core_ext:ordered_hash")).to be nil
    end

    it "returns a class if it matches the namespace" do
      expect(Thor::Util.find_by_namespace("app:broken:counter")).to eq(BrokenCounter)
    end

    it "matches classes default namespace" do
      expect(Thor::Util.find_by_namespace("scripts:my_script")).to eq(Scripts::MyScript)
    end
  end

  describe "#namespace_from_thor_class" do
    it "replaces constant nesting with command namespacing" do
      expect(Thor::Util.namespace_from_thor_class("Foo::Bar::Baz")).to eq("foo:bar:baz")
    end

    it "snake-cases component strings" do
      expect(Thor::Util.namespace_from_thor_class("FooBar::BarBaz::BazBoom")).to eq("foo_bar:bar_baz:baz_boom")
    end

    it "accepts class and module objects" do
      expect(Thor::Util.namespace_from_thor_class(Thor::CoreExt::OrderedHash)).to eq("thor:core_ext:ordered_hash")
      expect(Thor::Util.namespace_from_thor_class(Thor::Util)).to eq("thor:util")
    end

    it "removes Thor::Sandbox namespace" do
      expect(Thor::Util.namespace_from_thor_class("Thor::Sandbox::Package")).to eq("package")
    end
  end

  describe "#namespaces_in_content" do
    it "returns an array of names of constants defined in the string" do
      list = Thor::Util.namespaces_in_content("class Foo; class Bar < Thor; end; end; class Baz; class Bat; end; end")
      expect(list).to include("foo:bar")
      expect(list).not_to include("bar:bat")
    end

    it "doesn't put the newly-defined constants in the enclosing namespace" do
      Thor::Util.namespaces_in_content("class Blat; end")
      expect(defined?(Blat)).not_to be
      expect(defined?(Thor::Sandbox::Blat)).to be
    end
  end

  describe "#snake_case" do
    it "preserves no-cap strings" do
      expect(Thor::Util.snake_case("foo")).to eq("foo")
      expect(Thor::Util.snake_case("foo_bar")).to eq("foo_bar")
    end

    it "downcases all-caps strings" do
      expect(Thor::Util.snake_case("FOO")).to eq("foo")
      expect(Thor::Util.snake_case("FOO_BAR")).to eq("foo_bar")
    end

    it "downcases initial-cap strings" do
      expect(Thor::Util.snake_case("Foo")).to eq("foo")
    end

    it "replaces camel-casing with underscores" do
      expect(Thor::Util.snake_case("FooBarBaz")).to eq("foo_bar_baz")
      expect(Thor::Util.snake_case("Foo_BarBaz")).to eq("foo_bar_baz")
    end

    it "places underscores between multiple capitals" do
      expect(Thor::Util.snake_case("ABClass")).to eq("a_b_class")
    end
  end

  describe "#find_class_and_command_by_namespace" do
    it "returns a Thor::Group class if full namespace matches" do
      expect(Thor::Util.find_class_and_command_by_namespace("my_counter")).to eq([MyCounter, nil])
    end

    it "returns a Thor class if full namespace matches" do
      expect(Thor::Util.find_class_and_command_by_namespace("thor")).to eq([Thor, nil])
    end

    it "returns a Thor class and the command name" do
      expect(Thor::Util.find_class_and_command_by_namespace("thor:help")).to eq([Thor, "help"])
    end

    it "falls back in the namespace:command look up even if a full namespace does not match" do
      Thor.const_set(:Help, Module.new)
      expect(Thor::Util.find_class_and_command_by_namespace("thor:help")).to eq([Thor, "help"])
      Thor.send :remove_const, :Help
    end

    it "falls back on the default namespace class if nothing else matches" do
      expect(Thor::Util.find_class_and_command_by_namespace("test")).to eq([Scripts::MyDefaults, "test"])
    end
  end

  describe "#thor_classes_in" do
    it "returns thor classes inside the given class" do
      expect(Thor::Util.thor_classes_in(MyScript)).to eq([MyScript::AnotherScript])
      expect(Thor::Util.thor_classes_in(MyScript::AnotherScript)).to be_empty
    end
  end

  describe "#user_home" do
    before do
      allow(ENV).to receive(:[])
      Thor::Util.clear_user_home!
    end

    it "returns the user path if no variable is set on the environment" do
      expect(Thor::Util.user_home).to eq(File.expand_path("~"))
    end

    it "returns the *nix system path if file cannot be expanded and separator does not exist" do
      expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError)
      previous_value = File::ALT_SEPARATOR
      capture(:stderr) { File.const_set(:ALT_SEPARATOR, false) } # rubocop:disable SymbolName
      expect(Thor::Util.user_home).to eq("/")
      capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName
    end

    it "returns the windows system path if file cannot be expanded and a separator exists" do
      expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError)
      previous_value = File::ALT_SEPARATOR
      capture(:stderr) { File.const_set(:ALT_SEPARATOR, true) } # rubocop:disable SymbolName
      expect(Thor::Util.user_home).to eq("C:/")
      capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName
    end

    it "returns HOME/.thor if set" do
      allow(ENV).to receive(:[]).with("HOME").and_return("/home/user/")
      expect(Thor::Util.user_home).to eq("/home/user/")
    end

    it "returns path with HOMEDRIVE and HOMEPATH if set" do
      allow(ENV).to receive(:[]).with("HOMEDRIVE").and_return("D:/")
      allow(ENV).to receive(:[]).with("HOMEPATH").and_return("Documents and Settings/James")
      expect(Thor::Util.user_home).to eq("D:/Documents and Settings/James")
    end

    it "returns APPDATA/.thor if set" do
      allow(ENV).to receive(:[]).with("APPDATA").and_return("/home/user/")
      expect(Thor::Util.user_home).to eq("/home/user/")
    end
  end

  describe "#thor_root_glob" do
    before do
      allow(ENV).to receive(:[])
      Thor::Util.clear_user_home!
    end

    it "escapes globs in path" do
      allow(ENV).to receive(:[]).with("HOME").and_return("/home/user{1}/")
      expect(Dir).to receive(:[]).with('/home/user\\{1\\}/.thor/*').and_return([])
      expect(Thor::Util.thor_root_glob).to eq([])
    end
  end

  describe "#globs_for" do
    it "escapes globs in path" do
      expect(Thor::Util.globs_for("/home/apps{1}")).to eq([
        '/home/apps\\{1\\}/Thorfile',
        '/home/apps\\{1\\}/*.thor',
        '/home/apps\\{1\\}/tasks/*.thor',
        '/home/apps\\{1\\}/lib/tasks/*.thor'
      ])
    end
  end

  describe "#escape_globs" do
    it "escapes ? * { } [ ] glob characters" do
      expect(Thor::Util.escape_globs("apps?")).to eq('apps\\?')
      expect(Thor::Util.escape_globs("apps*")).to eq('apps\\*')
      expect(Thor::Util.escape_globs("apps {1}")).to eq('apps \\{1\\}')
      expect(Thor::Util.escape_globs("apps [1]")).to eq('apps \\[1\\]')
    end
  end
end