File: env_spec.cr

package info (click to toggle)
crystal 1.14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 24,384 kB
  • sloc: javascript: 6,400; sh: 695; makefile: 269; ansic: 121; python: 105; cpp: 77; xml: 32
file content (178 lines) | stat: -rw-r--r-- 4,759 bytes parent folder | download
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
require "spec"
require "./spec_helper"

describe "ENV" do
  # Preserves the existing environment for each spec.
  # To avoid potential circular definitions, this has to use the system methods
  # directly, rather than `ENV` or `with_env`.
  around_each do |example|
    old_env = {} of String => String
    Crystal::System::Env.each { |key, value| old_env[key] = value }

    begin
      example.run
    ensure
      keys = [] of String
      Crystal::System::Env.each { |key| keys << key }
      keys.each { |key| Crystal::System::Env.set(key, nil) }
      old_env.each { |key, value| Crystal::System::Env.set(key, value) }
    end
  end

  it "gets non existent key raises" do
    expect_raises KeyError, "Missing ENV key: \"NON-EXISTENT\"" do
      ENV["NON-EXISTENT"]
    end
  end

  it "gets non existent key as nilable" do
    ENV["NON-EXISTENT"]?.should be_nil
  end

  it "set and gets" do
    (ENV["FOO"] = "1").should eq("1")
    ENV["FOO"].should eq("1")
    ENV["FOO"]?.should eq("1")
  end

  {% if flag?(:win32) %}
    it "sets and gets case-insensitive" do
      (ENV["FOO"] = "1").should eq("1")
      ENV["Foo"].should eq("1")
      ENV["foo"]?.should eq("1")
    end
  {% else %}
    it "sets and gets case-sensitive" do
      ENV["FOO"] = "1"
      ENV["foo"]?.should be_nil
    end
  {% end %}

  it "sets to nil (same as delete)" do
    ENV["FOO"] = "1"
    ENV["FOO"]?.should_not be_nil
    ENV["FOO"] = nil
    ENV["FOO"]?.should be_nil
  end

  it "sets to empty string" do
    (ENV["FOO_EMPTY"] = "").should eq ""
    ENV["FOO_EMPTY"]?.should eq ""
  end

  it "does has_key?" do
    ENV["FOO"] = "1"
    ENV.has_key?("NON_EXISTENT").should be_false
    ENV.has_key?("FOO").should be_true
  end

  it "deletes a key" do
    ENV["FOO"] = "1"
    ENV.delete("FOO").should eq("1")
    ENV.delete("FOO").should be_nil
    ENV.has_key?("FOO").should be_false
  end

  it "does .keys" do
    %w(FOO BAR).each { |k| ENV.keys.should_not contain(k) }
    ENV["FOO"] = ENV["BAR"] = "1"
    %w(FOO BAR).each { |k| ENV.keys.should contain(k) }
  end

  it "does not have an empty key" do
    # Setting an empty key is invalid on both POSIX and Windows. So reporting an empty key
    # would always be a bug. And there *was* a bug - see win32/ Crystal::System::Env.each
    ENV.keys.should_not contain("")
  end

  it "does .values" do
    [1, 2].each { |i| ENV.values.should_not contain("SOMEVALUE_#{i}") }
    ENV["FOO"] = "SOMEVALUE_1"
    ENV["BAR"] = "SOMEVALUE_2"
    [1, 2].each { |i| ENV.values.should contain("SOMEVALUE_#{i}") }
  end

  describe "[]=" do
    it "disallows NUL-bytes in key" do
      expect_raises(ArgumentError, "String `key` contains null byte") do
        ENV["FOO\0BAR"] = "something"
      end
    end

    it "disallows NUL-bytes in key if value is nil" do
      expect_raises(ArgumentError, "String `key` contains null byte") do
        ENV["FOO\0BAR"] = nil
      end
    end

    it "disallows NUL-bytes in value" do
      expect_raises(ArgumentError, "String `value` contains null byte") do
        ENV["FOO"] = "BAR\0BAZ"
      end
    end
  end

  describe "fetch" do
    it "fetches with one argument" do
      ENV["1"] = "2"
      ENV.fetch("1").should eq("2")
    end

    it "fetches with default value" do
      ENV["1"] = "2"
      ENV.fetch("1", "3").should eq("2")
      ENV.fetch("2", "3").should eq("3")
    end

    it "fetches with block" do
      ENV["1"] = "2"
      ENV.fetch("1") { |k| k + "block" }.should eq("2")
      ENV.fetch("2") { |k| k + "block" }.should eq("2block")
      ENV.fetch("3") { 4 }.should eq(4)
    end

    it "fetches and raises" do
      ENV["1"] = "2"
      expect_raises KeyError, "Missing ENV key: \"2\"" do
        ENV.fetch("2")
      end
    end

    it "fetches arbitrary default value" do
      ENV.fetch("nonexistent", true).should be_true
    end
  end

  it "handles unicode" do
    ENV["TEST_UNICODE_1"] = "bar\u{d7ff}\u{10000}"
    ENV["TEST_UNICODE_2"] = "\u{1234}"
    ENV["TEST_UNICODE_1"].should eq "bar\u{d7ff}\u{10000}"
    ENV["TEST_UNICODE_2"].should eq "\u{1234}"

    values = {} of String => String
    ENV.each do |key, value|
      if key.starts_with?("TEST_UNICODE_")
        values[key] = value
      end
    end
    values.should eq({
      "TEST_UNICODE_1" => "bar\u{d7ff}\u{10000}",
      "TEST_UNICODE_2" => "\u{1234}",
    })
  end

  it "#to_h" do
    ENV["FOO"] = "foo"
    ENV.to_h["FOO"].should eq "foo"
  end

  {% if flag?(:win32) %}
    it "skips internal environment variables" do
      key = "=#{Path[Dir.current].drive}"
      ENV.has_key?(key).should be_false
      ENV[key]?.should be_nil
      expect_raises(ArgumentError) { ENV[key] = "foo" }
      expect_raises(ArgumentError) { ENV[key] = nil }
    end
  {% end %}
end