bluebird 0.1.0

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,115 @@
1
+ module Bluebird
2
+ class Tweet
3
+
4
+ include Twitter::Extractor
5
+
6
+ attr_reader :partials, :original_status, :media
7
+
8
+ def initialize(status, opts = {})
9
+ @original_status = status
10
+ @partials = extract_partials(status)
11
+ @media = opts[:media] if opts.has_key?(:media)
12
+ end
13
+
14
+ def status
15
+ partials.map { |partial| partial.content }.join
16
+ end
17
+
18
+ def length
19
+ total_partial_length + media_length
20
+ end
21
+
22
+ def text_partials
23
+ partials.select { |partial| partial.text? }
24
+ end
25
+
26
+ def url_partials
27
+ partials.select { |partial| partial.url? }
28
+ end
29
+
30
+ def mention_partials
31
+ partials.select { |partial| partial.mention? }
32
+ end
33
+
34
+ def hashtag_partials
35
+ partials.select { |partial| partial.hashtag? }
36
+ end
37
+
38
+ def cashtag_partials
39
+ partials.select { |partial| partial.cashtag? }
40
+ end
41
+
42
+ private
43
+
44
+ def total_partial_length
45
+ total = 0
46
+
47
+ partials.each do |partial|
48
+ total += partial.length
49
+ end
50
+
51
+ total
52
+ end
53
+
54
+ def media_length
55
+ media ? Config.characters_reserved_per_media : 0
56
+ end
57
+
58
+ def extract_partials(status)
59
+ entities = extract_entities_with_indices(status, extract_url_without_protocol: true)
60
+ length = status.char_length
61
+ index = 0
62
+ partials = []
63
+
64
+ entities.each do |entity|
65
+ first = entity[:indices].first
66
+ last = entity[:indices].last
67
+
68
+ add_partial(partials, status[index, first - index], :text)
69
+ add_partial(partials, status[first, last - first], entity_type(entity))
70
+
71
+ index = last
72
+ end
73
+
74
+ if ending_partial?(index, length)
75
+ add_partial(partials, status[index, length - index], :text)
76
+ end
77
+
78
+ partials
79
+ end
80
+
81
+ def add_partial(partials, content, partial_type)
82
+ if eligible_content?(content)
83
+ partial = Partial.new(content, partial_type)
84
+
85
+ if (last = partials.last)
86
+ last.next_partial = partial
87
+ partial.prev_partial = last
88
+ end
89
+
90
+ partials << partial
91
+ end
92
+ end
93
+
94
+ def entity_type(entity)
95
+ if entity.has_key?(:screen_name)
96
+ entity[:list_slug].empty? ? :mention : :list
97
+ elsif entity.has_key?(:hashtag)
98
+ :hashtag
99
+ elsif entity.has_key?(:url)
100
+ :url
101
+ elsif entity.has_key?(:cashtag)
102
+ :cashtag
103
+ end
104
+ end
105
+
106
+ def ending_partial?(index, length)
107
+ index <= length
108
+ end
109
+
110
+ def eligible_content?(content)
111
+ content.char_length > 0
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,3 @@
1
+ module Bluebird
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'bluebird'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -0,0 +1,444 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bluebird::Strategies::Squeeze::Strategy do
4
+
5
+ before(:all) do
6
+ Bluebird.configure do |config|
7
+ config.max_length = 20
8
+ config.characters_reserved_per_media = 5
9
+ end
10
+ end
11
+
12
+ let!(:strategy) { Bluebird::Strategies::Squeeze::Strategy }
13
+ let!(:config) { Bluebird::Config }
14
+
15
+ context 'When tweet is shorter than max' do
16
+ context 'and without leading whitespaces' do
17
+ context 'and without trailing whitespaces' do
18
+ context 'and without middle whitespaces' do
19
+ context 'and without media' do
20
+ it 'does not modify the tweet' do
21
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor')
22
+ strategy.run(tweet, config)
23
+ expect(tweet.status).to eq 'Lorem ipsum dolor'
24
+ end
25
+ end
26
+ context 'and with media' do
27
+ it 'does not modify the tweet' do
28
+ tweet = Bluebird::Tweet.new('Lorem ipsum', media: true)
29
+ strategy.run(tweet, config)
30
+ expect(tweet.status).to eq 'Lorem ipsum'
31
+ end
32
+ end
33
+ end
34
+ context 'and with middle whitespaces' do
35
+ context 'and without media' do
36
+ it 'does not modify the tweet' do
37
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor')
38
+ strategy.run(tweet, config)
39
+ expect(tweet.status).to eq 'Lorem ipsum dolor'
40
+ end
41
+ end
42
+ context 'and with media' do
43
+ it 'does not modify the tweet' do
44
+ tweet = Bluebird::Tweet.new('Lorem ipsum ', media: true)
45
+ strategy.run(tweet, config)
46
+ expect(tweet.status).to eq 'Lorem ipsum '
47
+ end
48
+ end
49
+ end
50
+ end
51
+ context 'and with trailing whitespaces' do
52
+ context 'and without middle whitespaces' do
53
+ context 'and without media' do
54
+ it 'does not modify the tweet' do
55
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor ')
56
+ strategy.run(tweet, config)
57
+ expect(tweet.status).to eq 'Lorem ipsum dolor '
58
+ end
59
+ end
60
+ context 'and with media' do
61
+ it 'does not modify the tweet' do
62
+ tweet = Bluebird::Tweet.new('Lorem ipsum ', media: true)
63
+ strategy.run(tweet, config)
64
+ expect(tweet.status).to eq 'Lorem ipsum '
65
+ end
66
+ end
67
+ end
68
+ context 'and with middle whitespaces' do
69
+ context 'and without media' do
70
+ it 'does not modify the tweet' do
71
+ tweet = Bluebird::Tweet.new('Lorem ipsum do ')
72
+ strategy.run(tweet, config)
73
+ expect(tweet.status).to eq 'Lorem ipsum do '
74
+ end
75
+ end
76
+ context 'and with media' do
77
+ it 'does not modify the tweet' do
78
+ tweet = Bluebird::Tweet.new('Lorem do ', media: true)
79
+ strategy.run(tweet, config)
80
+ expect(tweet.status).to eq 'Lorem do '
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ context 'and with leading whitespaces' do
87
+ context 'and without trailing whitespaces' do
88
+ context 'and without middle whitespaces' do
89
+ context 'and without media' do
90
+ it 'does not modify the tweet' do
91
+ tweet = Bluebird::Tweet.new(' Lorem ipsum do')
92
+ strategy.run(tweet, config)
93
+ expect(tweet.status).to eq ' Lorem ipsum do'
94
+ end
95
+ end
96
+ context 'and with media' do
97
+ it 'does not modify the tweet' do
98
+ tweet = Bluebird::Tweet.new(' Lorem do', media: true)
99
+ strategy.run(tweet, config)
100
+ expect(tweet.status).to eq ' Lorem do'
101
+ end
102
+ end
103
+ end
104
+ context 'and with middle whitespaces' do
105
+ context 'and without media' do
106
+ it 'does not modify the tweet' do
107
+ tweet = Bluebird::Tweet.new(' Lorem ipsum do')
108
+ strategy.run(tweet, config)
109
+ expect(tweet.status).to eq ' Lorem ipsum do'
110
+ end
111
+ end
112
+ context 'and with media' do
113
+ it 'does not modify the tweet' do
114
+ tweet = Bluebird::Tweet.new(' Lorem do', media: true)
115
+ strategy.run(tweet, config)
116
+ expect(tweet.status).to eq ' Lorem do'
117
+ end
118
+ end
119
+ end
120
+ end
121
+ context 'and with trailing whitespaces' do
122
+ context 'and without middle whitespaces' do
123
+ context 'and without media' do
124
+ it 'does not modify the tweet' do
125
+ tweet = Bluebird::Tweet.new(' Lorem ipsum do ')
126
+ strategy.run(tweet, config)
127
+ expect(tweet.status).to eq ' Lorem ipsum do '
128
+ end
129
+ end
130
+ context 'and with media' do
131
+ it 'does not modify the tweet' do
132
+ tweet = Bluebird::Tweet.new(' Lorem do ', media: true)
133
+ strategy.run(tweet, config)
134
+ expect(tweet.status).to eq ' Lorem do '
135
+ end
136
+ end
137
+ end
138
+ context 'and with middle whitespaces' do
139
+ context 'and without media' do
140
+ it 'does not modify the tweet' do
141
+ tweet = Bluebird::Tweet.new(' Lorem ipsum do ')
142
+ strategy.run(tweet, config)
143
+ expect(tweet.status).to eq ' Lorem ipsum do '
144
+ end
145
+ end
146
+ context 'and with media' do
147
+ it 'does not modify the tweet' do
148
+ tweet = Bluebird::Tweet.new(' Lorem do ', media: true)
149
+ strategy.run(tweet, config)
150
+ expect(tweet.status).to eq ' Lorem do '
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ context 'When tweet is longer than max' do
159
+ context 'and without leading whitespaces' do
160
+ context 'and without trailing whitespaces' do
161
+ context 'and without middle whitespaces' do
162
+ context 'and without media' do
163
+ it 'does not modify the tweet' do
164
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet')
165
+ strategy.run(tweet, config)
166
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet'
167
+ end
168
+ end
169
+ context 'and with media' do
170
+ it 'does not modify the tweet' do
171
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor', media: true)
172
+ strategy.run(tweet, config)
173
+ expect(tweet.status).to eq 'Lorem ipsum dolor'
174
+ end
175
+ end
176
+ end
177
+ context 'and with middle whitespaces' do
178
+ context 'and without media' do
179
+ it 'squeezes the middle whitespaces' do
180
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet')
181
+ strategy.run(tweet, config)
182
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet'
183
+ end
184
+ end
185
+ context 'and with media' do
186
+ it 'squeezes the middle whitespaces' do
187
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet', media: true)
188
+ strategy.run(tweet, config)
189
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet'
190
+ end
191
+ end
192
+ end
193
+ end
194
+ context 'and with trailing whitespaces' do
195
+ context 'and without middle whitespaces' do
196
+ context 'and without media' do
197
+ it 'squeezes the trailing whitespaces' do
198
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet ')
199
+ strategy.run(tweet, config)
200
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet '
201
+ end
202
+ end
203
+ context 'and with media' do
204
+ it 'squeezes the trailing whitespaces' do
205
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet ', media: true)
206
+ strategy.run(tweet, config)
207
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet '
208
+ end
209
+ end
210
+ end
211
+ context 'and with middle whitespaces' do
212
+ context 'and without media' do
213
+ it 'squeezes the trailing & middle whitespaces' do
214
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet ')
215
+ strategy.run(tweet, config)
216
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet '
217
+ end
218
+ end
219
+ context 'and with media' do
220
+ it 'squeezes the trailing & middle whitespaces' do
221
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor sit amet ', media: true)
222
+ strategy.run(tweet, config)
223
+ expect(tweet.status).to eq 'Lorem ipsum dolor sit amet '
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+ context 'and with leading whitespaces' do
230
+ context 'and without trailing whitespaces' do
231
+ context 'and without middle whitespaces' do
232
+ context 'and without media' do
233
+ it 'squeezes the leading whitespaces' do
234
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet')
235
+ strategy.run(tweet, config)
236
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet'
237
+ end
238
+ end
239
+ context 'and with media' do
240
+ it 'squeezes the leading whitespaces' do
241
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet', media: true)
242
+ strategy.run(tweet, config)
243
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet'
244
+ end
245
+ end
246
+ end
247
+ context 'and with middle whitespaces' do
248
+ context 'and without media' do
249
+ it 'squeezes the leading & middle whitespaces' do
250
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet')
251
+ strategy.run(tweet, config)
252
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet'
253
+ end
254
+ end
255
+ context 'and with media' do
256
+ it 'squeezes the leading & middle whitespaces' do
257
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet', media: true)
258
+ strategy.run(tweet, config)
259
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet'
260
+ end
261
+ end
262
+ end
263
+ end
264
+ context 'and with trailing whitespaces' do
265
+ context 'and without middle whitespaces' do
266
+ context 'and without media' do
267
+ it 'squeezes the leading & trailing whitespaces' do
268
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet ')
269
+ strategy.run(tweet, config)
270
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet '
271
+ end
272
+ end
273
+ context 'and with media' do
274
+ it 'squeezes the leading & trailing whitespaces' do
275
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet ', media: true)
276
+ strategy.run(tweet, config)
277
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet '
278
+ end
279
+ end
280
+ end
281
+ context 'and with middle whitespaces' do
282
+ context 'and without media' do
283
+ it 'squeezes the leading & middle & trailing whitespaces' do
284
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet ')
285
+ strategy.run(tweet, config)
286
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet '
287
+ end
288
+ end
289
+ context 'and with media' do
290
+ it 'squeezes the leading & middle & trailing whitespaces' do
291
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor sit amet ', media: true)
292
+ strategy.run(tweet, config)
293
+ expect(tweet.status).to eq ' Lorem ipsum dolor sit amet '
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
300
+
301
+ context "When tweet's length is equal to max" do
302
+ context 'and without leading whitespaces' do
303
+ context 'and without trailing whitespaces' do
304
+ context 'and without middle whitespaces' do
305
+ context 'and without media' do
306
+ it 'does not modify the tweet' do
307
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor si')
308
+ strategy.run(tweet, config)
309
+ expect(tweet.status).to eq 'Lorem ipsum dolor si'
310
+ end
311
+ end
312
+ context 'and with media' do
313
+ it 'does not modify the tweet' do
314
+ tweet = Bluebird::Tweet.new('Lorem ipsum dol', media: true)
315
+ strategy.run(tweet, config)
316
+ expect(tweet.status).to eq 'Lorem ipsum dol'
317
+ end
318
+ end
319
+ end
320
+ context 'and with middle whitespaces' do
321
+ context 'and without media' do
322
+ it 'does not modify the tweet' do
323
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor')
324
+ strategy.run(tweet, config)
325
+ expect(tweet.status).to eq 'Lorem ipsum dolor'
326
+ end
327
+ end
328
+ context 'and with media' do
329
+ it 'does not modify the tweet' do
330
+ tweet = Bluebird::Tweet.new('Lorem dolor', media: true)
331
+ strategy.run(tweet, config)
332
+ expect(tweet.status).to eq 'Lorem dolor'
333
+ end
334
+ end
335
+ end
336
+ end
337
+ context 'and with trailing whitespaces' do
338
+ context 'and without middle whitespaces' do
339
+ context 'and without media' do
340
+ it 'does not modify the tweet' do
341
+ tweet = Bluebird::Tweet.new('Lorem ipsum dolor ')
342
+ strategy.run(tweet, config)
343
+ expect(tweet.status).to eq 'Lorem ipsum dolor '
344
+ end
345
+ end
346
+ context 'and with media' do
347
+ it 'does not modify the tweet' do
348
+ tweet = Bluebird::Tweet.new('Loremx dolor ', media: true)
349
+ strategy.run(tweet, config)
350
+ expect(tweet.status).to eq 'Loremx dolor '
351
+ end
352
+ end
353
+ end
354
+ context 'and with middle whitespaces' do
355
+ context 'and without media' do
356
+ it 'does not modify the tweet' do
357
+ tweet = Bluebird::Tweet.new('Lorem ipsum dol ')
358
+ strategy.run(tweet, config)
359
+ expect(tweet.status).to eq 'Lorem ipsum dol '
360
+ end
361
+ end
362
+ context 'and with media' do
363
+ it 'does not modify the tweet' do
364
+ tweet = Bluebird::Tweet.new('Lorem dol ', media: true)
365
+ strategy.run(tweet, config)
366
+ expect(tweet.status).to eq 'Lorem dol '
367
+ end
368
+ end
369
+ end
370
+ end
371
+ end
372
+ context 'and with leading whitespaces' do
373
+ context 'and without trailing whitespaces' do
374
+ context 'and without middle whitespaces' do
375
+ context 'and without media' do
376
+ it 'does not modify the tweet' do
377
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dolor')
378
+ strategy.run(tweet, config)
379
+ expect(tweet.status).to eq ' Lorem ipsum dolor'
380
+ end
381
+ end
382
+ context 'and with media' do
383
+ it 'does not modify the tweet' do
384
+ tweet = Bluebird::Tweet.new(' Lorem ipsumd', media: true)
385
+ strategy.run(tweet, config)
386
+ expect(tweet.status).to eq ' Lorem ipsumd'
387
+ end
388
+ end
389
+ end
390
+ context 'and with middle whitespaces' do
391
+ context 'and without media' do
392
+ it 'does not modify the tweet' do
393
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dol')
394
+ strategy.run(tweet, config)
395
+ expect(tweet.status).to eq ' Lorem ipsum dol'
396
+ end
397
+ end
398
+ context 'and with media' do
399
+ it 'does not modify the tweet' do
400
+ tweet = Bluebird::Tweet.new(' Lorem dol', media: true)
401
+ strategy.run(tweet, config)
402
+ expect(tweet.status).to eq ' Lorem dol'
403
+ end
404
+ end
405
+ end
406
+ end
407
+ context 'and with trailing whitespaces' do
408
+ context 'and without middle whitespaces' do
409
+ context 'and without media' do
410
+ it 'does not modify the tweet' do
411
+ tweet = Bluebird::Tweet.new(' Lorem ipsum dol ')
412
+ strategy.run(tweet, config)
413
+ expect(tweet.status).to eq ' Lorem ipsum dol '
414
+ end
415
+ end
416
+ context 'and with media' do
417
+ it 'does not modify the tweet' do
418
+ tweet = Bluebird::Tweet.new(' Loremi dol ', media: true)
419
+ strategy.run(tweet, config)
420
+ expect(tweet.status).to eq ' Loremi dol '
421
+ end
422
+ end
423
+ end
424
+ context 'and with middle whitespaces' do
425
+ context 'and without media' do
426
+ it 'does not modify the tweet' do
427
+ tweet = Bluebird::Tweet.new(' Lorem ips dol ')
428
+ strategy.run(tweet, config)
429
+ expect(tweet.status).to eq ' Lorem ips dol '
430
+ end
431
+ end
432
+ context 'and with media' do
433
+ it 'does not modify the tweet' do
434
+ tweet = Bluebird::Tweet.new(' Lore dol ', media: true)
435
+ strategy.run(tweet, config)
436
+ expect(tweet.status).to eq ' Lore dol '
437
+ end
438
+ end
439
+ end
440
+ end
441
+ end
442
+ end
443
+
444
+ end