File: parser_spec.rb

package info (click to toggle)
ruby-dotenv 2.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 260 kB
  • sloc: ruby: 769; makefile: 6
file content (222 lines) | stat: -rw-r--r-- 6,667 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
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 "spec_helper"

describe Dotenv::Parser do
  def env(string)
    Dotenv::Parser.call(string, true)
  end

  it "parses unquoted values" do
    expect(env("FOO=bar")).to eql("FOO" => "bar")
  end

  it "parses values with spaces around equal sign" do
    expect(env("FOO =bar")).to eql("FOO" => "bar")
    expect(env("FOO= bar")).to eql("FOO" => "bar")
  end

  it "parses values with leading spaces" do
    expect(env("  FOO=bar")).to eql("FOO" => "bar")
  end

  it "parses values with following spaces" do
    expect(env("FOO=bar  ")).to eql("FOO" => "bar")
  end

  it "parses double quoted values" do
    expect(env('FOO="bar"')).to eql("FOO" => "bar")
  end

  it "parses double quoted values with following spaces" do
    expect(env('FOO="bar"  ')).to eql("FOO" => "bar")
  end

  it "parses single quoted values" do
    expect(env("FOO='bar'")).to eql("FOO" => "bar")
  end

  it "parses single quoted values with following spaces" do
    expect(env("FOO='bar'  ")).to eql("FOO" => "bar")
  end

  it "parses escaped double quotes" do
    expect(env('FOO="escaped\"bar"')).to eql("FOO" => 'escaped"bar')
  end

  it "parses empty values" do
    expect(env("FOO=")).to eql("FOO" => "")
  end

  it "expands variables found in values" do
    expect(env("FOO=test\nBAR=$FOO")).to eql("FOO" => "test", "BAR" => "test")
  end

  it "parses variables wrapped in brackets" do
    expect(env("FOO=test\nBAR=${FOO}bar"))
      .to eql("FOO" => "test", "BAR" => "testbar")
  end

  it "expands variables from ENV if not found in .env" do
    ENV["FOO"] = "test"
    expect(env("BAR=$FOO")).to eql("BAR" => "test")
  end

  it "expands variables from ENV if found in .env during load" do
    ENV["FOO"] = "test"
    expect(env("FOO=development\nBAR=${FOO}")["BAR"])
      .to eql("test")
  end

  it "doesn't expand variables from ENV if in local env in overload" do
    ENV["FOO"] = "test"
    expect(env("FOO=development\nBAR=${FOO}")["BAR"])
      .to eql("test")
  end

  it "expands undefined variables to an empty string" do
    expect(env("BAR=$FOO")).to eql("BAR" => "")
  end

  it "expands variables in double quoted strings" do
    expect(env("FOO=test\nBAR=\"quote $FOO\""))
      .to eql("FOO" => "test", "BAR" => "quote test")
  end

  it "does not expand variables in single quoted strings" do
    expect(env("BAR='quote $FOO'")).to eql("BAR" => "quote $FOO")
  end

  it "does not expand escaped variables" do
    expect(env('FOO="foo\$BAR"')).to eql("FOO" => "foo$BAR")
    expect(env('FOO="foo\${BAR}"')).to eql("FOO" => "foo${BAR}")
    expect(env("FOO=test\nBAR=\"foo\\${FOO} ${FOO}\""))
      .to eql("FOO" => "test", "BAR" => "foo${FOO} test")
  end

  it "parses yaml style options" do
    expect(env("OPTION_A: 1")).to eql("OPTION_A" => "1")
  end

  it "parses export keyword" do
    expect(env("export OPTION_A=2")).to eql("OPTION_A" => "2")
  end

  it "allows export line if you want to do it that way" do
    expect(env('OPTION_A=2
export OPTION_A')).to eql("OPTION_A" => "2")
  end

  it "allows export line if you want to do it that way and checks for unset"\
     " variables" do
    expect do
      env('OPTION_A=2
export OH_NO_NOT_SET')
    end.to raise_error(Dotenv::FormatError, 'Line "export OH_NO_NOT_SET"'\
                                            " has an unset variable")
  end

  it "expands newlines in quoted strings" do
    expect(env('FOO="bar\nbaz"')).to eql("FOO" => "bar\nbaz")
  end

  it 'parses variables with "." in the name' do
    expect(env("FOO.BAR=foobar")).to eql("FOO.BAR" => "foobar")
  end

  it "strips unquoted values" do
    expect(env("foo=bar ")).to eql("foo" => "bar") # not 'bar '
  end

  it "ignores lines that are not variable assignments" do
    expect(env("lol$wut")).to eql({})
  end

  it "ignores empty lines" do
    expect(env("\n \t  \nfoo=bar\n \nfizz=buzz"))
      .to eql("foo" => "bar", "fizz" => "buzz")
  end

  it "ignores inline comments" do
    expect(env("foo=bar # this is foo")).to eql("foo" => "bar")
  end

  it "allows # in quoted value" do
    expect(env('foo="bar#baz" # comment')).to eql("foo" => "bar#baz")
  end

  it "ignores comment lines" do
    expect(env("\n\n\n # HERE GOES FOO \nfoo=bar")).to eql("foo" => "bar")
  end

  it "ignores commented out variables" do
    expect(env("# HELLO=world\n")).to eql({})
  end

  it "ignores comment" do
    expect(env("# Uncomment to activate:\n")).to eql({})
  end

  it "parses # in quoted values" do
    expect(env('foo="ba#r"')).to eql("foo" => "ba#r")
    expect(env("foo='ba#r'")).to eql("foo" => "ba#r")
  end

  it "parses # in quoted values with following spaces" do
    expect(env('foo="ba#r"  ')).to eql("foo" => "ba#r")
    expect(env("foo='ba#r'  ")).to eql("foo" => "ba#r")
  end

  it "parses empty values" do
    expect(env("foo=")).to eql("foo" => "")
  end

  if RUBY_VERSION > "1.8.7"
    it "parses shell commands interpolated in $()" do
      expect(env("echo=$(echo hello)")).to eql("echo" => "hello")
    end

    it "allows balanced parentheses within interpolated shell commands" do
      expect(env('echo=$(echo "$(echo "$(echo "$(echo hello)")")")'))
        .to eql("echo" => "hello")
    end

    it "doesn't interpolate shell commands when escape says not to" do
      expect(env('echo=escaped-\$(echo hello)'))
        .to eql("echo" => "escaped-$(echo hello)")
    end

    it "is not thrown off by quotes in interpolated shell commands" do
      expect(env('interp=$(echo "Quotes won\'t be a problem")')["interp"])
        .to eql("Quotes won't be a problem")
    end

    it "supports carriage return" do
      expect(env("FOO=bar\rbaz=fbb")).to eql("FOO" => "bar", "baz" => "fbb")
    end

    it "supports carriage return combine with new line" do
      expect(env("FOO=bar\r\nbaz=fbb")).to eql("FOO" => "bar", "baz" => "fbb")
    end

    it "expands carriage return in quoted strings" do
      expect(env('FOO="bar\rbaz"')).to eql("FOO" => "bar\rbaz")
    end

    it "escape $ properly when no alphabets/numbers/_  are followed by it" do
      expect(env("FOO=\"bar\\$ \\$\\$\"")).to eql("FOO" => "bar$ $$")
    end

    # echo bar $ -> prints bar $ in the shell
    it "ignore $ when it is not escaped and no variable is followed by it" do
      expect(env("FOO=\"bar $ \"")).to eql("FOO" => "bar $ ")
    end

    # This functionality is not supported on JRuby or Rubinius
    if (!defined?(RUBY_ENGINE) || RUBY_ENGINE != "jruby") &&
       !defined?(Rubinius)
      it "substitutes shell variables within interpolated shell commands" do
        expect(env(%(VAR1=var1\ninterp=$(echo "VAR1 is $VAR1")))["interp"])
          .to eql("VAR1 is var1")
      end
    end
  end
end