redhead 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0892d60ca1c5336181bad77ba4d2b0f3182eef5d
4
+ data.tar.gz: a191d0961aa8f43ef90ebccaa8920e1075649ad0
5
+ SHA512:
6
+ metadata.gz: dd5b97bcb3e031d8dab2979d63654e455a4c0dc7e3a85d01ac1cb6a14f4423653255ad3066a961a3a9133a2731f0ffca0bf0d7d837006b157c92174fb5eb886c
7
+ data.tar.gz: cdd733e317bad53ab3fd68e700d9c0a09d730414513ca136fc1734f9cb5d3e94db80492a010d0be05101808ce666a6d8a3cf7364d76473917e703098c563e604
data/README.md CHANGED
@@ -26,8 +26,6 @@ To contribute:
26
26
  * Make a new feature branch: `git checkout -b some-new-thing master`
27
27
  * Pull request
28
28
 
29
- It will be assumed that your contribution will be licensed under the same terms as the project.
30
-
31
29
  ## Basics
32
30
 
33
31
  A variable `post` referencing a simple string can be wrapped up in a `Redhead::String` object.
@@ -35,18 +33,18 @@ A variable `post` referencing a simple string can be wrapped up in a `Redhead::S
35
33
  >> puts post
36
34
  Title: Redhead is for headers!
37
35
  Tags: redhead, ruby, headers
38
-
36
+
39
37
  Since time immemorial, ...
40
-
38
+
41
39
  >> post = Redhead::String[post]
42
40
  => +"Since time immemorial, ..."
43
-
41
+
44
42
  >> post.headers
45
43
  => { { :title => "Redhead is for headers" }, { :tags => "redhead, ruby, headers" } }
46
-
44
+
47
45
  >> post
48
46
  => +"Since time immemorial, ..."
49
-
47
+
50
48
  >> post.to_s
51
49
  => "Since time immemorial, ..."
52
50
 
@@ -60,26 +58,26 @@ A Redhead string has the functionality of a regular Ruby string.
60
58
 
61
59
  >> post.split(/,/).first.reverse
62
60
  => "lairomemmi emit ecniS"
63
-
61
+
64
62
  >> post.split(/ /).first
65
63
  => "Since"
66
-
64
+
67
65
  # Modifies the receiver!
68
66
  >> post.reverse!
69
67
  => "... ,lairomemmi emit ecniS"
70
-
68
+
71
69
  >> post.to_s
72
70
  => "..., lairomemmi emit ecniS"
73
-
71
+
74
72
  >> post.headers
75
73
  => { { :title => "Redhead is for headers" }, { :tags => "redhead, ruby, headers" } }
76
-
74
+
77
75
  >> post.replace("Better content.")
78
76
  => "Better content."
79
-
77
+
80
78
  >> post.to_s
81
79
  => "Better content."
82
-
80
+
83
81
  >> post.headers
84
82
  => { { :title => "Redhead is for headers" }, { :tags => "redhead, ruby, headers" } }
85
83
 
@@ -91,10 +89,10 @@ In addition, you get access to headers.
91
89
 
92
90
  >> post.headers[:title]
93
91
  => { :title => "Redhead is for headers!" }
94
-
92
+
95
93
  >> post.headers[:tags].to_s
96
94
  => "redhead, ruby, headers"
97
-
95
+
98
96
  >> post.headers.to_s
99
97
  => "Title: Redhead is for headers!\nTags: redhead, ruby, headers"
100
98
 
@@ -104,7 +102,7 @@ Modifying a header value is easy.
104
102
 
105
103
  >> post.headers[:title] = "A change of title."
106
104
  => "A change of title."
107
-
105
+
108
106
  >> post.headers[:title]
109
107
  => { :title => "A change of title." }
110
108
 
@@ -119,13 +117,13 @@ Alternatively, you can work with the header name-value object itself.
119
117
 
120
118
  >> title_header = post.headers[:title]
121
119
  => { :title => "A change of title." }
122
-
120
+
123
121
  >> title_header.value = "A better title."
124
122
  => "A better title."
125
-
123
+
126
124
  >> title_header
127
125
  => { :title => "A better title." }
128
-
126
+
129
127
  >> title_header.to_s
130
128
  => "Title: A better title."
131
129
 
@@ -135,10 +133,10 @@ You can also create and add new headers, in a similar way to modifying an existi
135
133
 
136
134
  >> post.headers[:awesome] = "very"
137
135
  => "very"
138
-
136
+
139
137
  >> post.headers
140
138
  => { { :title => "A better title." }, { :tags => "redhead, ruby, headers" }, { :awesome => "very" } }
141
-
139
+
142
140
  >> post.headers.to_s
143
141
  => "Title: A better title.\nTags: redhead, ruby, headers\nAwesome: very"
144
142
 
@@ -146,7 +144,7 @@ Since Ruby assignments always return the right-hand side, there is an alternativ
146
144
 
147
145
  >> post.headers.add(:amount_of_awesome, "high")
148
146
  => { :amount_of_awesome => "high" }
149
-
147
+
150
148
  >> post.headers[:amount_of_awesome].to_s
151
149
  => "Amount-Of-Awesome: high"
152
150
 
@@ -156,10 +154,10 @@ Deleting headers is just as easy.
156
154
 
157
155
  >> post.headers
158
156
  => { { :title => "A better title." }, { :tags => "redhead, ruby, headers" }, { :awesome => "very" }, { :amount_of_awesome => "high" } }
159
-
157
+
160
158
  >> post.headers.delete(:amount_of_awesome)
161
159
  => { :amount_of_awesome => "high" }
162
-
160
+
163
161
  >> post.headers
164
162
  => { { :title => "A better title." }, { :tags => "redhead, ruby, headers" }, { :awesome => "very" } }
165
163
 
@@ -178,7 +176,7 @@ Original header names are remembered from the input string, and not simply creat
178
176
  If the original string is:
179
177
 
180
178
  WaCKY fieLd NaME: value
181
-
179
+
182
180
  String's content.
183
181
 
184
182
  Then the header will be turned into a symbol:
@@ -210,16 +208,16 @@ Redhead has two main conversions which take place, related to header names. One
210
208
 
211
209
  >> str.headers
212
210
  => { { :awesome_rating => "quite" } }
213
-
211
+
214
212
  >> output = str.headers.to_s(:awesome_rating => "Something-Completely-Different") + "\n\n" + str.to_s
215
213
  => "Something-Completely-Different: quite\n\nString's content."
216
-
214
+
217
215
  >> input = Redhead::String[output]
218
216
  => "String's content."
219
-
217
+
220
218
  >> input.headers
221
219
  => { { :something_completely_different => "quite" } }
222
-
220
+
223
221
  >> input.headers[:awesome_rating]
224
222
  => nil
225
223
 
@@ -231,19 +229,19 @@ With the above caveats in mind, to actually change the raw header name, you can
231
229
 
232
230
  >> str.headers[:awesome] = "quite"
233
231
  => "quite"
234
-
232
+
235
233
  >> awesome_header = str.headers[:awesome]
236
234
  => { :awesome => "quite" }
237
-
235
+
238
236
  >> awesome_header.raw = "Some-Awe"
239
237
  => "Some-Awe"
240
-
238
+
241
239
  >> awesome_header
242
240
  => { :awesome => "quite" }
243
-
241
+
244
242
  >> awesome_header.to_s
245
243
  => "Some-Awe: quite"
246
-
244
+
247
245
  >> str.headers.to_s
248
246
  => "Some-Awe: quite"
249
247
 
@@ -252,19 +250,19 @@ You can also change the symbolic header name in the same fashion.
252
250
  # Delete to forget about the above
253
251
  >> str.headers.delete(:awesome)
254
252
  => { :awesome => "quite" }
255
-
253
+
256
254
  >> str.headers[:awesome] = "quite"
257
255
  => "quite"
258
-
256
+
259
257
  >> awesome_header = str.headers[:awesome]
260
258
  => { :awesome => "quite" }
261
-
259
+
262
260
  >> awesome_header.key = :different_kind_of_awesome
263
261
  => :different_kind_of_awesome
264
-
262
+
265
263
  >> awesome_header
266
264
  => { :different_kind_of_awesome => "quite" }
267
-
265
+
268
266
  >> awesome_header.to_s
269
267
  => "Awesome: quite"
270
268
 
@@ -272,16 +270,16 @@ The original symbolic header name will no longer work.
272
270
 
273
271
  >> str.headers[:awesome]
274
272
  => nil
275
-
273
+
276
274
  >> str.headers[:different_kind_of_awesome].key = :awesome
277
275
  => :awesome
278
-
276
+
279
277
  >> awesome_header
280
278
  => { :awesome => "quite" }
281
-
279
+
282
280
  >> awesome_header.to_s
283
281
  => "Awesome: quite"
284
-
282
+
285
283
  >> str.headers[:different_kind_of_awesome]
286
284
  => nil
287
285
 
@@ -289,19 +287,19 @@ As a further option, there is `headers!`, which allows more one-step control, wo
289
287
 
290
288
  >> str.headers
291
289
  => { { :awesome => "quite" } }
292
-
290
+
293
291
  >> str.headers[:temp] = "temp"
294
292
  => "temp"
295
-
293
+
296
294
  >> str.headers
297
295
  => { { :awesome => "quite" }, { :temp => "temp" } }
298
-
296
+
299
297
  >> str.headers.to_s
300
298
  => "Some-Awe: quite\nTemp: temp"
301
-
299
+
302
300
  >> str.headers!(:awesome => { :key => :awesome_rating, :raw => "Awesome-Rating" })
303
301
  => { { :awesome_rating => "quite" } }
304
-
302
+
305
303
  >> str.headers
306
304
  => { { :awesome => "quite" }, { :temp => "temp" } }
307
305
 
@@ -313,17 +311,17 @@ To work with a different raw header name, without modifying anything, you can pa
313
311
 
314
312
  >> str.headers
315
313
  => { { :awesome => "quite" }, { :temp => "temp" } }
316
-
314
+
317
315
  >> str.headers.to_s
318
316
  => "Awesome-Rating: quite\nTemp: temp"
319
-
317
+
320
318
  >> str.headers.to_s(:awesome => "Something-To-Do with Awesome-ness", :temp => "A very TEMPORARY header name")
321
319
  => "Something-To-Do with Awesome-ness: quite\nA very TEMPORARY header name"
322
-
320
+
323
321
  # Nothing changed.
324
322
  >> str.headers
325
323
  => { { :awesome => "quite" }, { :temp => "temp" } }
326
-
324
+
327
325
  >> str.headers.to_s
328
326
  => "Awesome-Rating: quite\nTemp: temp"
329
327
 
@@ -333,16 +331,16 @@ The custom raw header name can also be given explicitly at creation time.
333
331
 
334
332
  >> str.headers
335
333
  => { { :awesome => "quite" }, { :temp => "temp" } }
336
-
334
+
337
335
  >> str.headers.delete(:temp)
338
336
  => { :temp => "temp" }
339
-
337
+
340
338
  >> str.headers
341
339
  => { { :awesome => "quite" } }
342
-
340
+
343
341
  >> str.headers.add(:temporary, "temp", "A-Rather-Temporary-Value")
344
342
  => { :temp => "temp" }
345
-
343
+
346
344
  >> str.headers.to_s
347
345
  => "Awesome-Rating: quite\nA-Rather-Temporary-Value: temp"
348
346
 
@@ -1,20 +1,20 @@
1
1
  module Redhead
2
-
2
+
3
3
  # The character used to separate raw header names from their values.
4
4
  HEADER_NAME_VALUE_SEPARATOR_CHARACTER = ":"
5
-
5
+
6
6
  # The actual pattern to split header name from value. Uses the above character.
7
7
  HEADER_NAME_VALUE_SEPARATOR_PATTERN = /\s*#{HEADER_NAME_VALUE_SEPARATOR_CHARACTER}\s*/
8
-
8
+
9
9
  # The separator between header lines and regular body content.
10
10
  HEADERS_SEPARATOR = "\n\n"
11
-
11
+
12
12
  # The actual pattern used to split headers from content.
13
13
  HEADERS_SEPARATOR_PATTERN = /\r?\n\r?\n/m
14
-
14
+
15
15
  # The default code to convert a given key to a raw header name.
16
16
  TO_RAW = lambda { |key| key.to_s.split(/_/).map(&:capitalize).join("-") }
17
-
17
+
18
18
  # The default code to convert a given raw header name to a key.
19
19
  TO_KEY = lambda { |raw| raw.split(/[^a-z_]+/i).join("_").downcase.to_sym }
20
20
  end
@@ -1,13 +1,13 @@
1
1
  module Redhead
2
2
  class Header
3
3
  attr_accessor :key, :raw, :value
4
-
4
+
5
5
  def initialize(key, raw, value)
6
6
  @key = key
7
7
  @raw = raw
8
8
  @value = value
9
9
  end
10
-
10
+
11
11
  # Parses a string representing a header. Uses HEADER_NAME_VALUE_SEPARATOR_PATTERN
12
12
  # to determine the name and value parts of the string.
13
13
  def self.parse(header_string)
@@ -15,12 +15,12 @@ module Redhead
15
15
  raw = $`
16
16
  value = $'
17
17
  key = TO_KEY[raw]
18
-
18
+
19
19
  header = new(key, raw, value)
20
-
20
+
21
21
  header
22
22
  end
23
-
23
+
24
24
  # Returns the header as a string. If raw_name is given, this value is used as the raw header
25
25
  # name. If raw_name is not given, do one of two things:
26
26
  #
@@ -30,18 +30,18 @@ module Redhead
30
30
  r = raw_name || (block_given? ? yield(key) : raw)
31
31
  "#{r}#{Redhead::HEADER_NAME_VALUE_SEPARATOR_CHARACTER} #{value}"
32
32
  end
33
-
33
+
34
34
  # Does the same thing as #to_s, but instead of calling #raw in the last case, it computes the
35
35
  # raw header name dynamically from the key.
36
36
  def to_s!(raw_name = nil)
37
37
  r = raw_name || (block_given? ? yield(key) : TO_RAW[key])
38
38
  "#{r}#{Redhead::HEADER_NAME_VALUE_SEPARATOR_CHARACTER} #{value}"
39
39
  end
40
-
40
+
41
41
  def inspect
42
42
  "{ #{key.inspect} => #{value.inspect} }"
43
43
  end
44
-
44
+
45
45
  # Returns true if other_header has the same raw header name and value as self.
46
46
  def ==(other_header)
47
47
  raw == other_header.raw &&
@@ -1,12 +1,12 @@
1
1
  module Redhead
2
2
  class HeaderSet
3
3
  include Enumerable
4
-
4
+
5
5
  # Sets the headers of the set to _headers_. _headers_ is assumed to be ordered.
6
6
  def initialize(headers)
7
7
  @headers = headers
8
8
  end
9
-
9
+
10
10
  # Parses lines of header strings with Header.parse. Returns a new HeaderSet object
11
11
  # for the parsed headers.
12
12
  def self.parse(header_string)
@@ -14,10 +14,10 @@ module Redhead
14
14
  header_string.gsub(/\r\n/, "\n").split("\n").each do |str|
15
15
  headers << Redhead::Header.parse(str)
16
16
  end
17
-
17
+
18
18
  new(headers)
19
19
  end
20
-
20
+
21
21
  # Yields each header in the set.
22
22
  def each
23
23
  @headers.each { |h| yield h }
@@ -27,17 +27,17 @@ module Redhead
27
27
  def size
28
28
  @headers.size
29
29
  end
30
-
30
+
31
31
  # Returns true if the set of headers is empty.
32
32
  def empty?
33
33
  @headers.empty?
34
34
  end
35
-
35
+
36
36
  # Returns the first header found which has Header#key matching _key_.
37
37
  def [](key)
38
38
  @headers.find { |header| header.key == key }
39
39
  end
40
-
40
+
41
41
  # If there is a header in the set with a key matching _key_, then set its value to _value_.
42
42
  # If there is no header matching _key_, create a new header with the given key and value.
43
43
  def []=(key, value)
@@ -49,25 +49,25 @@ module Redhead
49
49
  self << new_header
50
50
  end
51
51
  end
52
-
52
+
53
53
  # Adds _header_ to the set of headers.
54
54
  def <<(header)
55
55
  @headers << header
56
56
  end
57
-
57
+
58
58
  # Similar to #[]= but allows manually setting the value of Header#raw to _raw_.
59
59
  def add(key, value, raw = nil)
60
60
  new_header = Redhead::Header.new(key, raw || TO_RAW[key], value)
61
61
  self << new_header
62
62
  new_header
63
63
  end
64
-
64
+
65
65
  # Removes any headers with key names matching _key_ from the set.
66
66
  def delete(key)
67
67
  header = self[key]
68
68
  @headers.reject! { |header| header.key == key } ? header : nil
69
69
  end
70
-
70
+
71
71
  # Calls #to_s on each header in the set, joining the result with newlines.
72
72
  #
73
73
  # If _hash_ has a key matching a header in the set, passes the value for that key in the hash
@@ -75,7 +75,7 @@ module Redhead
75
75
  # block to Header#to_s instead.
76
76
  def to_s(hash = {}, &block)
77
77
  return @headers.map { |header| header.to_s }.join("\n") if hash.empty? && !block_given?
78
-
78
+
79
79
  @headers.map do |header|
80
80
  if hash.has_key?(header.key)
81
81
  header.to_s(hash[header.key])
@@ -84,7 +84,7 @@ module Redhead
84
84
  end
85
85
  end.join("\n")
86
86
  end
87
-
87
+
88
88
  # If a block is given, passes the block to Header#to_s! Joins
89
89
  # the result with newlines.
90
90
  def to_s!(&block)
@@ -109,11 +109,11 @@ module Redhead
109
109
  end
110
110
 
111
111
  alias_method :to_hash, :to_h
112
-
112
+
113
113
  def inspect
114
114
  "{ #{@headers.map { |header| header.inspect }.join(", ")} }"
115
115
  end
116
-
116
+
117
117
  # Returns true if, for each header in the set, there is a header in _other_ for which header#==(other_header)
118
118
  # is true. Otherwise, returns false.
119
119
  def ==(other)
@@ -3,7 +3,7 @@ require "delegate"
3
3
  module Redhead
4
4
  class String < SimpleDelegator
5
5
  attr_reader :headers, :string
6
-
6
+
7
7
  class << self
8
8
  alias_method :[], :new
9
9
  end
@@ -27,12 +27,12 @@ module Redhead
27
27
  head_content = $`
28
28
 
29
29
  return false unless $`
30
-
30
+
31
31
  head_content.lines.all? do |l|
32
32
  l =~ HEADER_NAME_VALUE_SEPARATOR_PATTERN
33
33
  end
34
34
  end
35
-
35
+
36
36
  # Takes _string_, splits the headers from the content using HEADERS_SEPARATOR_PATTERN, then
37
37
  # creates the headers by calling HeaderSet.parse.
38
38
  def initialize(string)
@@ -45,6 +45,9 @@ module Redhead
45
45
 
46
46
  @headers = Redhead::HeaderSet.parse(header_content)
47
47
  else
48
+ @string = ""
49
+ super(@string)
50
+
48
51
  # we're dealing with only headers, so pass in the entire original string.
49
52
  # this lets us deal with inputs like new("foo: bar")
50
53
  @headers = Redhead::HeaderSet.parse(string)
@@ -55,21 +58,21 @@ module Redhead
55
58
  @headers = Redhead::HeaderSet.new([])
56
59
  end
57
60
  end
58
-
61
+
59
62
  # Returns the main body content wrapped in the Redhead String object.
60
63
  def to_s
61
- __getobj__
64
+ @string
62
65
  end
63
-
66
+
64
67
  def inspect
65
68
  "+#{string.inspect}"
66
69
  end
67
-
70
+
68
71
  # Returns true if self.headers == other.headers and self.string == other.string.
69
72
  def ==(other)
70
73
  headers == other.headers && string == other.string
71
74
  end
72
-
75
+
73
76
  # Modifies the headers in the set, using the given _hash_, which has the form
74
77
  #
75
78
  # { :some_header => { :raw => a, :key => b }, :another_header => ..., ... }
@@ -78,21 +81,15 @@ module Redhead
78
81
  # is _b_. Returns a HeaderSet object containing the changed Header objects.
79
82
  def headers!(hash)
80
83
  changing = headers.select { |header| hash.has_key?(header.key) }
81
-
84
+
82
85
  # modifies its elements!
83
86
  changing.each do |header|
84
87
  new_values = hash[header.key]
85
88
  header.raw = new_values[:raw] if new_values[:raw]
86
89
  header.key = new_values[:key] if new_values[:key]
87
90
  end
88
-
91
+
89
92
  Redhead::HeaderSet.new(changing)
90
93
  end
91
94
  end
92
-
93
- private
94
-
95
- def __getobj__
96
- string
97
- end
98
95
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "redhead"
3
- s.version = "0.0.8"
3
+ s.version = "0.0.9"
4
4
  s.authors = ["Adam Prescott"]
5
5
  s.email = ["adam@aprescott.com"]
6
6
  s.homepage = "https://github.com/aprescott/redhead"
@@ -8,10 +8,10 @@ describe Redhead::HeaderSet do
8
8
  @header = @headers.first
9
9
  @first_header_key = :a
10
10
  @header_set = Redhead::HeaderSet.new(@headers)
11
-
11
+
12
12
  @simple_headers = Redhead::HeaderSet.parse("A-Header: one\nA-Header-Two: two")
13
13
  end
14
-
14
+
15
15
  context "as a class" do
16
16
  describe ".parse" do
17
17
  it "calls Header.parse on each header line, to create a set of headers" do
@@ -22,26 +22,26 @@ describe Redhead::HeaderSet do
22
22
  end
23
23
  end
24
24
  end
25
-
25
+
26
26
  it "is Enumerable and responds to #each" do
27
27
  @header_set.is_a?(Enumerable).should be_true
28
28
  @header_set.respond_to?(:each).should be_true
29
29
  end
30
-
30
+
31
31
  describe "#[]" do
32
32
  context "for a key with a corresponding header" do
33
33
  it "takes a symbolic header name key and returns a header" do
34
34
  @header_set[:a].is_a?(Redhead::Header).should be_true
35
35
  end
36
36
  end
37
-
37
+
38
38
  context "for a key with no corresponding header" do
39
39
  it "returns nil" do
40
40
  @header_set[:something_non_existent].should be_nil
41
41
  end
42
42
  end
43
43
  end
44
-
44
+
45
45
  describe "#[]=" do
46
46
  context "for a key with a corresponding header" do
47
47
  it "sets a new header value" do
@@ -51,7 +51,7 @@ describe Redhead::HeaderSet do
51
51
  @header_set[@first_header_key].value.should == new_value
52
52
  end
53
53
  end
54
-
54
+
55
55
  context "for a key with no corresponding header" do
56
56
  it "creates a new header with this value" do
57
57
  new_value = "some brand new value"
@@ -61,7 +61,7 @@ describe Redhead::HeaderSet do
61
61
  end
62
62
  end
63
63
  end
64
-
64
+
65
65
  describe "#add" do
66
66
  context "being equivalent to #[]=" do
67
67
  def new_header(header_string)
@@ -69,21 +69,21 @@ describe Redhead::HeaderSet do
69
69
  @header_set.add(:brand_new_key, "some value")
70
70
  @header_set[:brand_new_key].should_not be_nil
71
71
  end
72
-
72
+
73
73
  it "parses the given header string, adds the new header to self and returns that header" do
74
74
  new_header(@header_set)
75
75
  end
76
-
76
+
77
77
  it "creates a new header with the given value" do
78
78
  new_header(@header_set)
79
79
  @header_set[:brand_new_key].value.should == "some value"
80
80
  end
81
-
81
+
82
82
  it "returns a Redhead::Header object" do
83
83
  @header_set.add(:brand_new_key, "some value").class.should == Redhead::Header
84
84
  end
85
85
  end
86
-
86
+
87
87
  it "takes an optional third argument which sets the value of the raw header" do
88
88
  @header_set.add(:foo, "bar", "BAZ!")
89
89
  @header_set[:foo].value.should == "bar"
@@ -91,7 +91,7 @@ describe Redhead::HeaderSet do
91
91
  @header_set[:foo].raw.should == "BAZ!"
92
92
  end
93
93
  end
94
-
94
+
95
95
  describe "#delete" do
96
96
  it "removes a header from the set" do
97
97
  @header_set[:brand_new_key].should be_nil
@@ -101,13 +101,13 @@ describe Redhead::HeaderSet do
101
101
  @header_set.delete(:brand_new_key)
102
102
  @header_set[:brand_new_key].should be_nil
103
103
  end
104
-
104
+
105
105
  it "returns the deleted header" do
106
106
  @header_set[:brand_new_key] = "test"
107
107
  h = @header_set[:brand_new_key]
108
108
  @header_set.delete(:brand_new_key).should == h
109
109
  end
110
-
110
+
111
111
  it "returns nil if there is no header corresponding to the key" do
112
112
  @header_set[:brand_new_key].should be_nil
113
113
  @header_set.delete(:brand_new_key).should be_nil
@@ -142,85 +142,85 @@ describe Redhead::HeaderSet do
142
142
  @header_set.size.should == @headers.size
143
143
  end
144
144
  end
145
-
145
+
146
146
  describe "#to_s" do
147
147
  it "equals the individual header to_s results, joined with newlines" do
148
148
  @header_set.to_s.should == @headers.map { |header| header.to_s }.join("\n")
149
149
  end
150
-
150
+
151
151
  context %Q{with a hash argument :a => "something raw"} do
152
152
  def modified_full_header_set_string
153
153
  str = "something raw: value_a\n"
154
154
  str += @headers[1..-1].map { |e| "header_#{e.key}: value_#{e.key}" }.join("\n")
155
155
  str
156
156
  end
157
-
157
+
158
158
  it %Q{sets the header with key :a to have #raw == "one" and #value == 1} do
159
159
  str = modified_full_header_set_string
160
-
160
+
161
161
  @header_set.to_s(:a => "something raw").should == str
162
162
  @header_set[:a].raw.should_not == "something raw"
163
163
  @header_set[:a].raw.should == "header_a"
164
164
  end
165
-
165
+
166
166
  it "does not leave a side-effect" do
167
167
  str = modified_full_header_set_string
168
-
168
+
169
169
  @header_set.to_s(:a => "something raw").should == str
170
170
  @header_set[:a].raw.should_not == "something raw"
171
171
  @header_set[:a].raw.should == "header_a"
172
172
  end
173
173
  end
174
-
174
+
175
175
  context "with a block argument" do
176
176
  def modified_full_header_set_string
177
177
  @headers.map { |e| "#{yield e.key}: value_#{e.key}" }.join("\n")
178
178
  end
179
-
179
+
180
180
  it "uses the given block to convert #key to a raw header, for each header in the set" do
181
181
  @header_set.to_s { "testing" + "testing" }.should == modified_full_header_set_string { "testing" + "testing" }
182
-
182
+
183
183
  new_to_raw = proc { |x| x.to_s.upcase.reverse }
184
-
184
+
185
185
  @header_set.to_s(&new_to_raw).should == modified_full_header_set_string(&new_to_raw)
186
186
  end
187
-
187
+
188
188
  it "follows the hash argument first, falling back to the given block" do
189
189
  @header_set.to_s(:a => "something raw") { "NOT RAW AT ALL" }.split("\n").first.should == "something raw: value_a"
190
190
  end
191
191
  end
192
192
  end
193
-
193
+
194
194
  describe "#to_s!" do
195
195
  context "without a block" do
196
196
  it "calls to_s! on each header in the set, joining the results with newlines" do
197
197
  @simple_headers.to_s!.should == @simple_headers.map { |header| header.to_s! }.join("\n")
198
198
  end
199
199
  end
200
-
200
+
201
201
  context "with a block" do
202
202
  it "calls to_s! on each header in the set, passing the given block, joining the results with newlines" do
203
203
  @header_set.to_s! { "Total foo bar" }.should == @headers.map { |header| "Total foo bar: #{header.value}" }.join("\n")
204
204
  end
205
205
  end
206
206
  end
207
-
207
+
208
208
  describe "#==(other_header)" do
209
209
  it "is sane." do
210
210
  @header_set.should == @header_set
211
-
211
+
212
212
  Redhead::HeaderSet.parse("Test: test").should == Redhead::HeaderSet.parse("Test: test")
213
213
  end
214
-
214
+
215
215
  it "returns true if, for every header in self, there is a corresponding header in other_header equal to it, using Header#==" do
216
216
  one, two = @header_set.partition { |header| header.key.to_s < @header_set.to_a[1].key.to_s }.map { |part| Redhead::HeaderSet.new(part) }
217
-
217
+
218
218
  one.all? { |a| two.find { |b| a == b } }.should be_false
219
219
  # sanity check with any?
220
220
  one.any? { |a| two.find { |b| a == b } }.should be_false
221
-
221
+
222
222
  one << two.first # create an overlap
223
-
223
+
224
224
  one.all? { |a| two.find { |b| a == b } }.should be_false
225
225
  # sanity check with any?
226
226
  one.any? { |a| two.find { |b| a == b } }.should be_true
@@ -6,21 +6,21 @@ describe Redhead::Header do
6
6
  @header_raw_name = "A-Header-Name"
7
7
  @header_value = "some value"
8
8
  @separator = Redhead::HEADER_NAME_VALUE_SEPARATOR_CHARACTER
9
-
9
+
10
10
  @full_header_string = "#{@header_raw_name}#{@separator} #{@header_value}"
11
-
11
+
12
12
  @header = Redhead::Header.new(:a_header_name, "A-Header-Name", "some value")
13
13
  @header_copy = Redhead::Header.new(:a_header_name, "A-Header-Name", "some value")
14
-
14
+
15
15
  @different_header_raw_name = "An original HEADER name"
16
16
  @header_different_name = Redhead::Header.new(:a_header_name, "An original HEADER name", "something here")
17
17
  end
18
-
18
+
19
19
  context "as a class" do
20
20
  it "responds to :parse" do
21
21
  Redhead::Header.respond_to?(:parse).should be_true
22
22
  end
23
-
23
+
24
24
  describe "self.parse" do
25
25
  it "parses a string and returns a header" do
26
26
  parsed_header = Redhead::Header.parse(@full_header_string)
@@ -30,19 +30,19 @@ describe Redhead::Header do
30
30
  parsed_header.value.should == @header_value
31
31
  parsed_header.raw.should == @header_raw_name
32
32
  end
33
-
33
+
34
34
  it "ignores consecutive non-separating characters by default" do
35
35
  parsed_header = Redhead::Header.parse("one very strange!!! header: anything")
36
36
  parsed_header.key.should == :one_very_strange_header
37
37
  end
38
-
38
+
39
39
  it "ignores whitespace around `:` by default" do
40
40
  spaces = []
41
-
41
+
42
42
  20.times do |n|
43
43
  spaces << [" "*rand(n), " "*rand(n)]
44
44
  end
45
-
45
+
46
46
  spaces.each do |before, after|
47
47
  Redhead::Header.parse("#{@header_raw_name}#{before}:#{after}#{@header_value}").key.should == @header_name
48
48
  end
@@ -55,92 +55,92 @@ describe Redhead::Header do
55
55
  end
56
56
  end
57
57
  end
58
-
58
+
59
59
  describe "#key" do
60
60
  it "returns the symbolic header name" do
61
61
  @header.key.should == :a_header_name
62
62
  end
63
63
  end
64
-
64
+
65
65
  describe "#raw" do
66
66
  it "returns the raw header name stored at creation time" do
67
67
  @header.raw.should == @header_raw_name
68
68
  end
69
69
  end
70
-
70
+
71
71
  describe "#value" do
72
72
  it "returns the header value" do
73
73
  @header.value.should == @header_value
74
74
  end
75
75
  end
76
-
76
+
77
77
  describe "#value=" do
78
78
  it "sets a new header value" do
79
79
  @header.value = "new value"
80
80
  @header.value.should == "new value"
81
81
  end
82
82
  end
83
-
83
+
84
84
  describe "#to_s" do
85
85
  it "returns <raw><separator> <value>" do
86
86
  @header.to_s.should == @full_header_string
87
87
  end
88
-
88
+
89
89
  context "with a block" do
90
90
  it "uses the given block to convert #key to a raw header, and returns the raw string" do
91
91
  @header.to_s { "test" }.should == "test#{@separator} #{@header_value}"
92
92
  end
93
93
  end
94
-
94
+
95
95
  it "takes an optional argument which specifies the raw header to use, without side-effects" do
96
96
  @header.to_s("test").should_not == @full_header_string
97
97
  @header.to_s("test").should == "test#{@separator} #{@header_value}"
98
98
  @header.to_s.should == @full_header_string
99
99
  @header.to_s.should_not == "test#{@separator} #{@header_value}"
100
100
  end
101
-
101
+
102
102
  it "ignores the given block if there is an explicit raw header name" do
103
103
  @header.to_s("test") { "foo" }.should_not == "foo#{@separator} #{@header_value}"
104
104
  @header.to_s("test") { "foo" }.should == "test#{@separator} #{@header_value}"
105
105
  end
106
106
  end
107
-
107
+
108
108
  describe "#==(other)" do
109
109
  it "returns true if self.raw == other.raw && self.value == other.value, otherwise false" do
110
110
  @header_copy.value = "something else entirely"
111
111
  @header.should_not == @header_copy
112
-
112
+
113
113
  # same raw name, same value
114
114
  Redhead::Header.new(:a_header_name, "A-Header-Name", "a").should == Redhead::Header.new(:a_header_name, "A-Header-Name", "a")
115
-
115
+
116
116
  # same raw name, different value
117
117
  Redhead::Header.new(:a_header_name, "A-Header-Name", "a").should_not == Redhead::Header.new(:a_header_name, "A-Header-Name", "aaaaaaa")
118
-
118
+
119
119
  # different raw name, same value
120
120
  Redhead::Header.new(:a_header_name, "A-Header-Name", "a").should_not == Redhead::Header.new(:a_header_name, "A-Header-Nameeeeeeee", "a")
121
121
  end
122
122
  end
123
-
123
+
124
124
  describe "#to_s!" do
125
125
  it "returns <computed_raw_header><separator> <value>" do
126
126
  @header.to_s!.should == "#{@header_raw_name}#{@separator} #{@header_value}"
127
127
  @header_different_name.to_s!.should == "#{@header_raw_name}#{@separator} something here"
128
128
  end
129
-
129
+
130
130
  context "with a block argument" do
131
131
  it "uses the given block to compute the raw header name" do
132
132
  @header.to_s! { "testing" }.should == "testing: #{@header_value}"
133
133
  @header.to_s! { |x| x.to_s.upcase.reverse.gsub("_", "-") }.should == "#{@header_raw_name.to_s.upcase.reverse}: #{@header_value}"
134
134
  end
135
135
  end
136
-
136
+
137
137
  it "takes an optional argument specifying the raw header name to use, without side-effects" do
138
138
  @header.to_s!("test").should_not == @full_header_string
139
139
  @header.to_s!("test").should == "test#{@separator} #{@header_value}"
140
140
  @header.to_s!.should == @full_header_string
141
141
  @header.to_s!.should_not == "test#{@separator} #{@header_value}"
142
142
  end
143
-
143
+
144
144
  it "ignores the given block if there is an explicit raw header name" do
145
145
  @header.to_s("test") { "foo" }.should_not == "foo#{@separator} #{@header_value}"
146
146
  @header.to_s("test") { "foo" }.should == "test#{@separator} #{@header_value}"
@@ -7,7 +7,7 @@ describe Redhead::String do
7
7
  @rh_string = Redhead::String[@string]
8
8
  @copy_rh_string = Redhead::String[@string.clone]
9
9
  end
10
-
10
+
11
11
  context "as a class" do
12
12
  describe "self.[]" do
13
13
  it "is equal (==) in result to using .new" do
@@ -39,6 +39,11 @@ describe Redhead::String do
39
39
  h.value.should == "bar:baz"
40
40
  end
41
41
  end
42
+
43
+ it "handles header-only inputs" do
44
+ Redhead::String["foo: bar"].to_s.should eq("")
45
+ Redhead::String["foo: bar\n"].to_s.should eq("")
46
+ end
42
47
  end
43
48
 
44
49
  describe ".has_headers?" do
@@ -59,23 +64,23 @@ describe Redhead::String do
59
64
  end
60
65
  end
61
66
  end
62
-
67
+
63
68
  context "before any modifications:" do
64
69
  describe "#to_s" do
65
70
  it "returns a proper String instance" do
66
71
  @rh_string.to_s.class.should == String
67
72
  end
68
-
73
+
69
74
  it "is the contents of the header-less string" do
70
75
  @rh_string.to_s.should == @string_content
71
76
  end
72
-
77
+
73
78
  it "is not in fact the same object as its contained string" do
74
79
  @rh_string.to_s.equal?(@string_content).should be_false
75
80
  end
76
81
  end
77
82
  end
78
-
83
+
79
84
  describe "#headers" do
80
85
  it "returns a Redhead::HeaderSet object" do
81
86
  @rh_string.headers.is_a?(Redhead::HeaderSet).should be_true
@@ -86,54 +91,54 @@ describe Redhead::String do
86
91
  s.headers.size.should == 0
87
92
  end
88
93
  end
89
-
94
+
90
95
  it "provides regular String methods" do
91
96
  String.instance_methods(false).each do |m|
92
97
  @rh_string.respond_to?(m).should be_true
93
98
  end
94
99
  end
95
-
100
+
96
101
  it "modifies its containing string with bang-methods" do
97
102
  orig = @rh_string.to_s.dup
98
103
  @rh_string.reverse!
99
104
  @rh_string.to_s.should == orig.reverse
100
105
  @rh_string.reverse!
101
-
106
+
102
107
  orig = @rh_string.to_s.dup
103
108
  @rh_string.upcase!
104
109
  @rh_string.to_s.should == orig.upcase
105
110
  end
106
-
111
+
107
112
  describe "#==" do
108
113
  it "returns true if the two Redhead strings contain equal headersets (using HeaderSet#==) and the same string content (using String#==)" do
109
114
  @rh_string.should == @rh_string
110
115
  @copy_rh_string.should == @rh_string
111
-
116
+
112
117
  # change the copy
113
118
  @copy_rh_string.headers[:a_header_value] = "something"
114
119
  @other_rh_string = @copy_rh_string
115
-
120
+
116
121
  @rh_string.headers.should_not == @other_rh_string.headers
117
122
  @rh_string.string.should == @other_rh_string.string
118
123
  @rh_string.should_not == @other_rh_string
119
124
  end
120
125
  end
121
-
126
+
122
127
  describe %Q{#headers!(:a => { :raw => "random raw", :key => "random key" })} do
123
128
  it %Q{modifies the header for key :a by calling raw="random raw", and key="random_key"} do
124
129
  header = @rh_string.headers[:a_header_value]
125
130
  header.raw.should_not == "random raw"
126
131
  header.key.should_not == "random key"
127
-
132
+
128
133
  @rh_string.headers!(:a_header_value => { :raw => "random raw", :key => "random key" })
129
134
  header.raw.should == "random raw"
130
135
  header.key.should == "random key"
131
136
  end
132
-
137
+
133
138
  it "ignores keys with no matching header" do
134
139
  expect { @rh_string.headers!(:lorem_ipsum_dolor_sit_amettttt => {}) }.to_not raise_error
135
140
  end
136
-
141
+
137
142
  it "returns only the changed headers" do
138
143
  @rh_string.headers!(:lorem_ipsum_dolor_sit_amet => {}).empty?.should be_true
139
144
  @rh_string.headers!(:a_header_value => {}).empty?.should_not be_true
metadata CHANGED
@@ -1,46 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redhead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
5
- prerelease:
4
+ version: 0.0.9
6
5
  platform: ruby
7
6
  authors:
8
7
  - Adam Prescott
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
11
+ date: 2014-02-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rspec
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  description: String header metadata.
@@ -50,48 +45,47 @@ executables: []
50
45
  extensions: []
51
46
  extra_rdoc_files: []
52
47
  files:
48
+ - ".gemtest"
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
53
52
  - lib/redhead.rb
54
- - lib/redhead/redhead_string.rb
55
53
  - lib/redhead/header.rb
56
54
  - lib/redhead/header_set.rb
57
- - test/test_helper.rb
58
- - test/redhead_spec.rb
59
- - test/redhead_string_spec.rb
55
+ - lib/redhead/redhead_string.rb
56
+ - rakefile
57
+ - redhead.gemspec
60
58
  - test/header_set_spec.rb
61
59
  - test/header_spec.rb
62
- - redhead.gemspec
63
- - .gemtest
64
- - LICENSE
65
- - Gemfile
66
- - rakefile
67
- - README.md
60
+ - test/redhead_spec.rb
61
+ - test/redhead_string_spec.rb
62
+ - test/test_helper.rb
68
63
  homepage: https://github.com/aprescott/redhead
69
64
  licenses: []
65
+ metadata: {}
70
66
  post_install_message:
71
67
  rdoc_options: []
72
68
  require_paths:
73
69
  - lib
74
70
  required_ruby_version: !ruby/object:Gem::Requirement
75
- none: false
76
71
  requirements:
77
- - - ! '>='
72
+ - - ">="
78
73
  - !ruby/object:Gem::Version
79
74
  version: '0'
80
75
  required_rubygems_version: !ruby/object:Gem::Requirement
81
- none: false
82
76
  requirements:
83
- - - ! '>='
77
+ - - ">="
84
78
  - !ruby/object:Gem::Version
85
79
  version: '0'
86
80
  requirements: []
87
81
  rubyforge_project:
88
- rubygems_version: 1.8.24
82
+ rubygems_version: 2.2.0
89
83
  signing_key:
90
- specification_version: 3
84
+ specification_version: 4
91
85
  summary: String header metadata.
92
86
  test_files:
93
87
  - test/test_helper.rb
94
- - test/redhead_spec.rb
95
88
  - test/redhead_string_spec.rb
96
89
  - test/header_set_spec.rb
97
90
  - test/header_spec.rb
91
+ - test/redhead_spec.rb