inifile 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +61 -0
- data/lib/inifile.rb +264 -0
- data/test/data/bad_1.ini +6 -0
- data/test/data/bad_2.ini +6 -0
- data/test/data/comment.ini +5 -0
- data/test/data/good.ini +17 -0
- data/test/data/mixed_comment.ini +7 -0
- data/test/data/param.ini +5 -0
- data/test/test_inifile.rb +277 -0
- metadata +55 -0
data/README.txt
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
= Ruby INI File Parser and Writer
|
3
|
+
|
4
|
+
== Introduction
|
5
|
+
|
6
|
+
An initialization file, or INI file, is a configuration file that contains
|
7
|
+
configuration data for Microsoft Windows based applications. Starting with
|
8
|
+
Windows 95, the INI file format was superseded but not entirely replaced by a
|
9
|
+
registry database in Microsoft operating systems.
|
10
|
+
|
11
|
+
Although made popular by Windows, INI files can be used on any system thanks
|
12
|
+
to their flexibility. They allow a program to store configuration data, which
|
13
|
+
can then be easily parsed and changed.
|
14
|
+
|
15
|
+
== File Format
|
16
|
+
|
17
|
+
A typical INI file might look like this:
|
18
|
+
|
19
|
+
[section1]
|
20
|
+
|
21
|
+
; some comment on section1
|
22
|
+
var1 = foo
|
23
|
+
var2 = doodle
|
24
|
+
|
25
|
+
[section2]
|
26
|
+
|
27
|
+
; another comment
|
28
|
+
var1 = baz
|
29
|
+
var2 = shoodle
|
30
|
+
|
31
|
+
=== Format
|
32
|
+
|
33
|
+
This describes the elements of the INI file format:
|
34
|
+
|
35
|
+
* *Sections*: Section declarations start with '[' and end with ']' as in [section1] and [section2] above. And sections start with section declarations.
|
36
|
+
* *Parameters*: The "var1 = foo" above is an example of a parameter (also known as an item). Parameters are made up of a key ('var1'), equals sign ('='), and a value ('foo').
|
37
|
+
* *Comments*: All the lines starting with a ';' are assumed to be comments, and are ignored.
|
38
|
+
|
39
|
+
=== Differences
|
40
|
+
|
41
|
+
The format of INI files is not well defined. Many programs interpret their
|
42
|
+
structure differently than the basic structure that was defined in the above
|
43
|
+
example. The following is a basic list of some of the differences:
|
44
|
+
|
45
|
+
* *Comments*: Programs like Samba accept either ';' or '#' as comments. Comments can be added after parameters with several formats.
|
46
|
+
* *Backslashes*: Adding a backslash '\' allows you to continue the value from one line to another. Some formats also allow various escapes with a '\', such as '\n' for newline.
|
47
|
+
* <b>Duplicate parameters</b>: Most of the time, you can't have two parameters with the same name in one section. Therefore one can say that parameters are local to the section. Although this behavior can vary between implementations, it is advisable to stick with this rule.
|
48
|
+
* <b>Duplicate sections</b>: If you have more than one section with the same name then the last section overrides the previous one. (Some implementations will merge them if they have different keys.)
|
49
|
+
* Some implementations allow ':' in place of '='.
|
50
|
+
|
51
|
+
== This Package
|
52
|
+
|
53
|
+
This package supports the standard INI file format described in the *Format*
|
54
|
+
section above. The following differences are also supported:
|
55
|
+
|
56
|
+
* *Comments*: The comment character can be specified when an +IniFile+ is created. The comment character must be the first non-whitespace character on a line.
|
57
|
+
* *Backslashes*: Backslashes are not supported by this package.
|
58
|
+
* <b>Duplicate parameters</b>: Duplicate parameters are allowed in a single section. The last parameter value is the one that will be stored in the +IniFile+.
|
59
|
+
* <b>Duplicate sections</b>: Duplicate sections will be merged. Parameters duplicated between to the two sections follow the duplicate parameters rule above.
|
60
|
+
* *Parameters*: The parameter separator character can be specified when an +IniFile+ is created.
|
61
|
+
|
data/lib/inifile.rb
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
# $Id: inifile.rb 57 2006-11-19 20:51:45Z tpease $
|
2
|
+
|
3
|
+
#
|
4
|
+
# This class represents the INI file and can be used to parse, modify,
|
5
|
+
# and write INI files.
|
6
|
+
#
|
7
|
+
class IniFile
|
8
|
+
|
9
|
+
# :stopdoc:
|
10
|
+
class Error < StandardError; end
|
11
|
+
# :startdoc:
|
12
|
+
|
13
|
+
#
|
14
|
+
# call-seq:
|
15
|
+
# IniFile.load( filename )
|
16
|
+
# IniFile.load( filename, options )
|
17
|
+
#
|
18
|
+
# Open the given _filename_ and load the contetns of the INI file.
|
19
|
+
# The following _options_ can be passed to this method:
|
20
|
+
#
|
21
|
+
# :comment => ';' The line comment character(s)
|
22
|
+
# :parameter => '=' The parameter / value separator
|
23
|
+
#
|
24
|
+
def self.load( filename, opts = {} )
|
25
|
+
new(filename, opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# call-seq:
|
30
|
+
# IniFile.new( filename )
|
31
|
+
# IniFile.new( filename, options )
|
32
|
+
#
|
33
|
+
# Create a new INI file using the given _filename_. If _filename_
|
34
|
+
# exists and is a regular file, then its contents will be parsed.
|
35
|
+
# The following _options_ can be passed to this method:
|
36
|
+
#
|
37
|
+
# :comment => ';' The line comment character(s)
|
38
|
+
# :parameter => '=' The parameter / value separator
|
39
|
+
#
|
40
|
+
def initialize( filename, opts = {} )
|
41
|
+
@fn = filename
|
42
|
+
@comment = opts[:comment] || ';'
|
43
|
+
@param = opts[:parameter] || '='
|
44
|
+
@ini = Hash.new {|h,k| h[k] = Hash.new}
|
45
|
+
|
46
|
+
@rgxp_comment = %r/\A\s*\z|\A\s*[#{@comment}]/
|
47
|
+
@rgxp_section = %r/\A\s*\[([^\]]+)\]/o
|
48
|
+
@rgxp_param = %r/\A([^#{@param}]+)#{@param}(.*)\z/
|
49
|
+
|
50
|
+
parse
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# call-seq:
|
55
|
+
# write
|
56
|
+
# write( filename )
|
57
|
+
#
|
58
|
+
# Write the INI file contents to the filesystem. The given _filename_
|
59
|
+
# will be used to write the file. If _filename_ is not given, then the
|
60
|
+
# named used when constructing this object will be used.
|
61
|
+
#
|
62
|
+
def write( filename = nil )
|
63
|
+
@fn = filename unless filename.nil?
|
64
|
+
|
65
|
+
::File.open(@fn, 'w') do |f|
|
66
|
+
@ini.each do |section,hash|
|
67
|
+
f.puts "[#{section}]"
|
68
|
+
hash.each {|param,val| f.puts "#{param} #{@param} #{val}"}
|
69
|
+
f.puts
|
70
|
+
end
|
71
|
+
end
|
72
|
+
self
|
73
|
+
end
|
74
|
+
alias :save :write
|
75
|
+
|
76
|
+
#
|
77
|
+
# call-seq:
|
78
|
+
# each {|section, parameter, value| block}
|
79
|
+
#
|
80
|
+
# Yield each _section_, _parameter_, _value_ in turn to the given
|
81
|
+
# _block_. The method returns immediately if no block is supplied.
|
82
|
+
#
|
83
|
+
def each
|
84
|
+
return unless block_given?
|
85
|
+
@ini.each do |section,hash|
|
86
|
+
hash.each do |param,val|
|
87
|
+
yield section, param, val
|
88
|
+
end
|
89
|
+
end
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# call-seq:
|
95
|
+
# each_section {|section| block}
|
96
|
+
#
|
97
|
+
# Yield each _section_ in turn to the given _block_. The method returns
|
98
|
+
# immediately if no block is supplied.
|
99
|
+
#
|
100
|
+
def each_section
|
101
|
+
return unless block_given?
|
102
|
+
@ini.each_key {|section| yield section}
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# call-seq:
|
108
|
+
# delete_section( section )
|
109
|
+
#
|
110
|
+
# Deletes the named _section_ from the INI file. Returns the
|
111
|
+
# parameter / value pairs if the section exists in the INI file. Otherwise,
|
112
|
+
# returns +nil+.
|
113
|
+
#
|
114
|
+
def delete_section( section )
|
115
|
+
@ini.delete section.to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# call-seq:
|
120
|
+
# ini_file[section]
|
121
|
+
#
|
122
|
+
# Get the hash of parameter/value pairs for the given _section_. If the
|
123
|
+
# _section_ hash does not exist it will be created.
|
124
|
+
#
|
125
|
+
def []( section )
|
126
|
+
return nil if section.nil?
|
127
|
+
@ini[section.to_s]
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# call-seq:
|
132
|
+
# has_section?( section )
|
133
|
+
#
|
134
|
+
# Returns +true+ if the named _section_ exists in the INI file.
|
135
|
+
#
|
136
|
+
def has_section?( section )
|
137
|
+
@ini.has_key? section.to_s
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# call-seq:
|
142
|
+
# sections
|
143
|
+
#
|
144
|
+
# Returns an array of the section names.
|
145
|
+
#
|
146
|
+
def sections
|
147
|
+
@ini.keys
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# call-seq:
|
152
|
+
# freeze
|
153
|
+
#
|
154
|
+
# Freeze the state of the +IniFile+ object. Any attempts to change the
|
155
|
+
# object will raise an error.
|
156
|
+
#
|
157
|
+
def freeze
|
158
|
+
super
|
159
|
+
@ini.each_value {|h| h.freeze}
|
160
|
+
@ini.freeze
|
161
|
+
self
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# call-seq:
|
166
|
+
# taint
|
167
|
+
#
|
168
|
+
# Marks the INI file as tainted -- this will traverse each section marking
|
169
|
+
# each section as tainted as well.
|
170
|
+
#
|
171
|
+
def taint
|
172
|
+
super
|
173
|
+
@ini.each_value {|h| h.taint}
|
174
|
+
@ini.taint
|
175
|
+
self
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# call-seq:
|
180
|
+
# dup
|
181
|
+
#
|
182
|
+
# Produces a duplicate of this INI file. The duplicate is independent of the
|
183
|
+
# original -- i.e. the duplicate can be modified without changing the
|
184
|
+
# orgiinal. The tainted state of the original is copied to the duplicate.
|
185
|
+
#
|
186
|
+
def dup
|
187
|
+
other = super
|
188
|
+
other.instance_variable_set(:@ini, Hash.new {|h,k| h[k] = Hash.new})
|
189
|
+
@ini.each_pair {|s,h| other[s].merge! h}
|
190
|
+
other.taint if self.tainted?
|
191
|
+
other
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# call-seq:
|
196
|
+
# clone
|
197
|
+
#
|
198
|
+
# Produces a duplicate of this INI file. The duplicate is independent of the
|
199
|
+
# original -- i.e. the duplicate can be modified without changing the
|
200
|
+
# orgiinal. The tainted state and the frozen state of the original is copied
|
201
|
+
# to the duplicate.
|
202
|
+
#
|
203
|
+
def clone
|
204
|
+
other = dup
|
205
|
+
other.freeze if self.frozen?
|
206
|
+
other
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# call-seq:
|
211
|
+
# eql?( other )
|
212
|
+
#
|
213
|
+
# Returns +true+ if the _other_ object is equivalent to this INI file. For
|
214
|
+
# two INI files to be equivalent, they must have the same sections with the
|
215
|
+
# same parameter / value pairs in each section.
|
216
|
+
#
|
217
|
+
def eql?( other )
|
218
|
+
return true if equal? other
|
219
|
+
return false unless other.instance_of? self.class
|
220
|
+
@ini == other.instance_variable_get(:@ini)
|
221
|
+
end
|
222
|
+
alias :== :eql?
|
223
|
+
|
224
|
+
|
225
|
+
private
|
226
|
+
#
|
227
|
+
# call-seq
|
228
|
+
# parse
|
229
|
+
#
|
230
|
+
# Parse the ini file contents.
|
231
|
+
#
|
232
|
+
def parse
|
233
|
+
return unless ::Kernel.test ?f, @fn
|
234
|
+
section = nil
|
235
|
+
|
236
|
+
::File.open(@fn, 'r') do |f|
|
237
|
+
while line = f.gets
|
238
|
+
line = line.chomp
|
239
|
+
|
240
|
+
case line
|
241
|
+
# ignore blank lines and comment lines
|
242
|
+
when @rgxp_comment: next
|
243
|
+
|
244
|
+
# this is a section declaration
|
245
|
+
when @rgxp_section: section = @ini[$1.strip]
|
246
|
+
|
247
|
+
# otherwise we have a parameter
|
248
|
+
when @rgxp_param
|
249
|
+
begin
|
250
|
+
section[$1.strip] = $2.strip
|
251
|
+
rescue NoMethodError
|
252
|
+
raise Error, "parameter encountered before first section"
|
253
|
+
end
|
254
|
+
|
255
|
+
else
|
256
|
+
raise Error, "could not parse line '#{line}"
|
257
|
+
end
|
258
|
+
end # while
|
259
|
+
end # File.open
|
260
|
+
end
|
261
|
+
|
262
|
+
end # class IniFile
|
263
|
+
|
264
|
+
# EOF
|
data/test/data/bad_1.ini
ADDED
data/test/data/bad_2.ini
ADDED
data/test/data/good.ini
ADDED
data/test/data/param.ini
ADDED
@@ -0,0 +1,277 @@
|
|
1
|
+
# Code Generated by ZenTest v. 3.3.0
|
2
|
+
# classname: asrt / meth = ratio%
|
3
|
+
# Rini::IniFile: 0 / 9 = 0.00%
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'inifile'
|
7
|
+
rescue LoadError
|
8
|
+
require 'rubygems'
|
9
|
+
require 'inifile'
|
10
|
+
end
|
11
|
+
|
12
|
+
begin; require 'turn'; rescue LoadError; end
|
13
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
14
|
+
|
15
|
+
class TestIniFile < Test::Unit::TestCase
|
16
|
+
|
17
|
+
def setup
|
18
|
+
@ini_file = ::IniFile.new 'test/data/good.ini'
|
19
|
+
@contents = [
|
20
|
+
['section_one', 'one', '1'],
|
21
|
+
['section_one', 'two', '2'],
|
22
|
+
['section_two', 'three', '3'],
|
23
|
+
['section three', 'four', '4'],
|
24
|
+
['section three', 'five', '5'],
|
25
|
+
['section three', 'six', '6'],
|
26
|
+
['section_five', 'seven and eight', '7 & 8']
|
27
|
+
].sort
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_class_load
|
31
|
+
ini_file = ::IniFile.load 'test/data/good.ini'
|
32
|
+
assert_instance_of ::IniFile, ini_file
|
33
|
+
|
34
|
+
# see if we can parse different style comments
|
35
|
+
assert_raise(::IniFile::Error) {::IniFile.load 'test/data/comment.ini'}
|
36
|
+
|
37
|
+
ini_file = ::IniFile.load 'test/data/comment.ini', :comment => '#'
|
38
|
+
assert_instance_of ::IniFile, ini_file
|
39
|
+
|
40
|
+
# see if we can parse mixed style comments
|
41
|
+
assert_raise(::IniFile::Error) {::IniFile.load 'test/data/mixed_comment.ini'}
|
42
|
+
|
43
|
+
ini_file = ::IniFile.load 'test/data/mixed_comment.ini', :comment => ';#'
|
44
|
+
assert_instance_of ::IniFile, ini_file
|
45
|
+
|
46
|
+
# see if we can parse different style param separators
|
47
|
+
assert_raise(::IniFile::Error) {::IniFile.load 'test/data/param.ini'}
|
48
|
+
|
49
|
+
ini_file = ::IniFile.load 'test/data/param.ini', :parameter => ':'
|
50
|
+
assert_instance_of ::IniFile, ini_file
|
51
|
+
|
52
|
+
# make sure we error out on files with bad lines
|
53
|
+
assert_raise(::IniFile::Error) {::IniFile.load 'test/data/bad_1.ini'}
|
54
|
+
assert_raise(::IniFile::Error) {::IniFile.load 'test/data/bad_2.ini'}
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_clone
|
58
|
+
clone = @ini_file.clone
|
59
|
+
assert_equal @ini_file, clone
|
60
|
+
assert !clone.tainted?
|
61
|
+
assert !clone.frozen?
|
62
|
+
|
63
|
+
# the clone should be completely independent of the original
|
64
|
+
clone['new_section']['one'] = 1
|
65
|
+
assert_not_equal @ini_file, clone
|
66
|
+
|
67
|
+
# the tainted state is copied to clones
|
68
|
+
@ini_file.taint
|
69
|
+
assert @ini_file.tainted?
|
70
|
+
|
71
|
+
clone = @ini_file.clone
|
72
|
+
assert clone.tainted?
|
73
|
+
|
74
|
+
# the frozen state is also copied to clones
|
75
|
+
@ini_file.freeze
|
76
|
+
assert @ini_file.frozen?
|
77
|
+
|
78
|
+
clone = @ini_file.clone
|
79
|
+
assert clone.tainted?
|
80
|
+
assert clone.frozen?
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_delete_section
|
84
|
+
assert_nil @ini_file.delete_section('section_nil')
|
85
|
+
|
86
|
+
h = {'one' => '1', 'two' => '2'}
|
87
|
+
assert_equal true, @ini_file.has_section?('section_one')
|
88
|
+
assert_equal h, @ini_file.delete_section('section_one')
|
89
|
+
assert_equal false, @ini_file.has_section?('section_one')
|
90
|
+
assert_nil @ini_file.delete_section('section_one')
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_dup
|
94
|
+
dup = @ini_file.dup
|
95
|
+
assert_equal @ini_file, dup
|
96
|
+
assert !dup.tainted?
|
97
|
+
assert !dup.frozen?
|
98
|
+
|
99
|
+
# the duplicate should be completely independent of the original
|
100
|
+
dup['new_section']['one'] = 1
|
101
|
+
assert_not_equal @ini_file, dup
|
102
|
+
|
103
|
+
# the tainted state is copied to duplicates
|
104
|
+
@ini_file.taint
|
105
|
+
assert @ini_file.tainted?
|
106
|
+
|
107
|
+
dup = @ini_file.dup
|
108
|
+
assert dup.tainted?
|
109
|
+
|
110
|
+
# the frozen state, however, is not
|
111
|
+
@ini_file.freeze
|
112
|
+
assert @ini_file.frozen?
|
113
|
+
|
114
|
+
dup = @ini_file.dup
|
115
|
+
assert dup.tainted?
|
116
|
+
assert !dup.frozen?
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_each
|
120
|
+
ary = []
|
121
|
+
@ini_file.each {|*args| ary << args}
|
122
|
+
|
123
|
+
assert_equal @contents, ary.sort
|
124
|
+
|
125
|
+
ary = []
|
126
|
+
::IniFile.new('temp.ini').each {|*args| ary << args}
|
127
|
+
assert_equal [], ary
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_each_section
|
131
|
+
expected = [
|
132
|
+
'section_one', 'section_two', 'section three',
|
133
|
+
'section_four', 'section_five'
|
134
|
+
].sort
|
135
|
+
|
136
|
+
ary = []
|
137
|
+
@ini_file.each_section {|section| ary << section}
|
138
|
+
|
139
|
+
assert_equal expected, ary.sort
|
140
|
+
|
141
|
+
ary = []
|
142
|
+
::IniFile.new('temp.ini').each_section {|section| ary << section}
|
143
|
+
assert_equal [], ary
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_eql_eh
|
147
|
+
assert @ini_file.eql?(@ini_file)
|
148
|
+
assert @ini_file.eql?(@ini_file.clone)
|
149
|
+
assert !@ini_file.eql?('string')
|
150
|
+
assert !@ini_file.eql?(IniFile.new(''))
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_freeze
|
154
|
+
assert_equal false, @ini_file.frozen?
|
155
|
+
@ini_file.each_section do |s|
|
156
|
+
assert_equal false, @ini_file[s].frozen?
|
157
|
+
end
|
158
|
+
|
159
|
+
@ini_file.freeze
|
160
|
+
|
161
|
+
assert_equal true, @ini_file.frozen?
|
162
|
+
@ini_file.each_section do |s|
|
163
|
+
assert_equal true, @ini_file[s].frozen?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_has_section_eh
|
168
|
+
assert_equal true, @ini_file.has_section?('section_one')
|
169
|
+
assert_equal false, @ini_file.has_section?('section_ten')
|
170
|
+
assert_equal true, @ini_file.has_section?(:section_two)
|
171
|
+
assert_equal false, @ini_file.has_section?(nil)
|
172
|
+
|
173
|
+
ini_file = ::IniFile.new 'temp.ini'
|
174
|
+
assert_equal false, ini_file.has_section?('section_one')
|
175
|
+
assert_equal false, ini_file.has_section?('one')
|
176
|
+
assert_equal false, ini_file.has_section?('two')
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_index
|
180
|
+
expected = {
|
181
|
+
'one' => '1',
|
182
|
+
'two' => '2'
|
183
|
+
}
|
184
|
+
assert_equal expected, @ini_file[:section_one]
|
185
|
+
|
186
|
+
expected = {'three' => '3'}
|
187
|
+
assert_equal expected, @ini_file['section_two']
|
188
|
+
|
189
|
+
expected = {
|
190
|
+
'four' => '4',
|
191
|
+
'five' => '5',
|
192
|
+
'six' => '6',
|
193
|
+
}
|
194
|
+
assert_equal expected, @ini_file['section three']
|
195
|
+
|
196
|
+
expected = {}
|
197
|
+
assert_equal expected, @ini_file['section_four']
|
198
|
+
|
199
|
+
expected = {'seven and eight' => '7 & 8'}
|
200
|
+
assert_equal expected, @ini_file['section_five']
|
201
|
+
|
202
|
+
expected = {}
|
203
|
+
assert_equal expected, @ini_file['section_six']
|
204
|
+
|
205
|
+
assert_nil @ini_file[nil]
|
206
|
+
|
207
|
+
expected = {}
|
208
|
+
ini_file = ::IniFile.new 'temp.ini'
|
209
|
+
assert_equal expected, ini_file['section_one']
|
210
|
+
assert_equal expected, ini_file['one']
|
211
|
+
assert_nil ini_file[nil]
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_initialize
|
215
|
+
# see if we can parse different style comments
|
216
|
+
assert_raise(::IniFile::Error) {::IniFile.new 'test/data/comment.ini'}
|
217
|
+
|
218
|
+
ini_file = ::IniFile.new 'test/data/comment.ini', :comment => '#'
|
219
|
+
assert_equal true, ini_file.has_section?('section_one')
|
220
|
+
|
221
|
+
# see if we can parse different style param separators
|
222
|
+
assert_raise(::IniFile::Error) {::IniFile.new 'test/data/param.ini'}
|
223
|
+
|
224
|
+
ini_file = ::IniFile.new 'test/data/param.ini', :parameter => ':'
|
225
|
+
assert_equal true, ini_file.has_section?('section_one')
|
226
|
+
assert_equal '1', ini_file['section_one']['one']
|
227
|
+
assert_equal '2', ini_file['section_one']['two']
|
228
|
+
|
229
|
+
# make sure we error out on files with bad lines
|
230
|
+
assert_raise(::IniFile::Error) {::IniFile.new 'test/data/bad_1.ini'}
|
231
|
+
assert_raise(::IniFile::Error) {::IniFile.new 'test/data/bad_2.ini'}
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_sections
|
235
|
+
expected = [
|
236
|
+
'section_one', 'section_two', 'section three',
|
237
|
+
'section_four', 'section_five'
|
238
|
+
].sort
|
239
|
+
|
240
|
+
assert_equal expected, @ini_file.sections.sort
|
241
|
+
|
242
|
+
ini_file = ::IniFile.new 'temp.ini'
|
243
|
+
assert_equal [], ini_file.sections
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_taint
|
247
|
+
assert_equal false, @ini_file.tainted?
|
248
|
+
@ini_file.each_section do |s|
|
249
|
+
assert_equal false, @ini_file[s].tainted?
|
250
|
+
end
|
251
|
+
|
252
|
+
@ini_file.taint
|
253
|
+
|
254
|
+
assert_equal true, @ini_file.tainted?
|
255
|
+
@ini_file.each_section do |s|
|
256
|
+
assert_equal true, @ini_file[s].tainted?
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_write
|
261
|
+
tmp = 'test/data/temp.ini'
|
262
|
+
::File.delete tmp if ::Kernel.test(?f, tmp)
|
263
|
+
|
264
|
+
@ini_file.save tmp
|
265
|
+
assert_equal true, ::Kernel.test(?f, tmp)
|
266
|
+
|
267
|
+
::File.delete tmp if ::Kernel.test(?f, tmp)
|
268
|
+
|
269
|
+
ini_file = ::IniFile.new tmp
|
270
|
+
ini_file.save
|
271
|
+
assert_nil ::Kernel.test(?s, tmp)
|
272
|
+
|
273
|
+
::File.delete tmp if ::Kernel.test(?f, tmp)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# EOF
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: inifile
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2006-11-26 00:00:00 -07:00
|
8
|
+
summary: INI file reader and writer
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
- test
|
12
|
+
email: tim.pease@gmail.com
|
13
|
+
homepage:
|
14
|
+
rubyforge_project: codeforpeople.com
|
15
|
+
description: Although made popular by Windows, INI files can be used on any system thanks to their flexibility. They allow a program to store configuration data, which can then be easily parsed and changed. Two notable systems that use the INI format are Samba and Trac. This is a native Ruby package for reading and writing INI files.
|
16
|
+
autorequire:
|
17
|
+
default_executable:
|
18
|
+
bindir: bin
|
19
|
+
has_rdoc: true
|
20
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
post_install_message:
|
30
|
+
authors:
|
31
|
+
- Tim Pease
|
32
|
+
files:
|
33
|
+
- README.txt
|
34
|
+
- lib/inifile.rb
|
35
|
+
- test/data/bad_1.ini
|
36
|
+
- test/data/bad_2.ini
|
37
|
+
- test/data/comment.ini
|
38
|
+
- test/data/good.ini
|
39
|
+
- test/data/mixed_comment.ini
|
40
|
+
- test/data/param.ini
|
41
|
+
- test/test_inifile.rb
|
42
|
+
test_files:
|
43
|
+
- test/test_inifile.rb
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
extra_rdoc_files: []
|
47
|
+
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
dependencies: []
|
55
|
+
|