junkfood 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.
Files changed (43) hide show
  1. data/.document +11 -0
  2. data/.gitignore +6 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +76 -0
  5. data/LICENSE +202 -0
  6. data/NOTICE +4 -0
  7. data/README.md +375 -0
  8. data/Rakefile +51 -0
  9. data/VERSION +1 -0
  10. data/junkfood.gemspec +147 -0
  11. data/lib/junkfood/adler32.rb +102 -0
  12. data/lib/junkfood/adler32_pure.rb +112 -0
  13. data/lib/junkfood/assert.rb +75 -0
  14. data/lib/junkfood/base32.rb +198 -0
  15. data/lib/junkfood/ceb/base_command.rb +62 -0
  16. data/lib/junkfood/ceb/base_event.rb +42 -0
  17. data/lib/junkfood/ceb/bus.rb +152 -0
  18. data/lib/junkfood/ceb/executors/command_executor.rb +44 -0
  19. data/lib/junkfood/ceb/executors/delayed_job_command_executor.rb +61 -0
  20. data/lib/junkfood/ceb/executors/event_executor.rb +35 -0
  21. data/lib/junkfood/ceb/executors.rb +25 -0
  22. data/lib/junkfood/ceb.rb +27 -0
  23. data/lib/junkfood/one_time.rb +247 -0
  24. data/lib/junkfood/paperclip_string_io.rb +66 -0
  25. data/lib/junkfood/settings.rb +67 -0
  26. data/lib/junkfood.rb +29 -0
  27. data/spec/.rspec +1 -0
  28. data/spec/junkfood/adler32_pure_spec.rb +16 -0
  29. data/spec/junkfood/adler32_spec.rb +16 -0
  30. data/spec/junkfood/assert_spec.rb +84 -0
  31. data/spec/junkfood/base32_spec.rb +39 -0
  32. data/spec/junkfood/ceb/base_command_spec.rb +73 -0
  33. data/spec/junkfood/ceb/base_event_spec.rb +67 -0
  34. data/spec/junkfood/ceb/bus_spec.rb +153 -0
  35. data/spec/junkfood/ceb/executors/command_executor_spec.rb +24 -0
  36. data/spec/junkfood/ceb/executors/delayed_job_command_executor_spec.rb +5 -0
  37. data/spec/junkfood/ceb/executors/event_executor_spec.rb +18 -0
  38. data/spec/junkfood/one_time_spec.rb +167 -0
  39. data/spec/junkfood/paperclip_string_io_spec.rb +40 -0
  40. data/spec/junkfood/settings_spec.rb +7 -0
  41. data/spec/junkfood_spec.rb +4 -0
  42. data/spec/spec_helper.rb +20 -0
  43. metadata +372 -0
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe 'Junkfood::Base32' do
4
+ it 'should encode into an ASCII string' do
5
+ str = Junkfood::Base32.encode '1234567890abcdefghijklmnopqrstuvwxyz'
6
+ str.string.should eql(
7
+ 'GEZDGNBVGY3TQOJQMFRGGZDFMZTWQ2LKNNWG23TPOBYXE43UOV3HO6DZPI')
8
+ str.string.encoding.should eql(Encoding::ASCII)
9
+ end
10
+
11
+ it 'should decode into a BINARY string' do
12
+ str = Junkfood::Base32.decode(
13
+ 'GEZDGNBVGY3TQOJQMFRGGZDFMZTWQ2LKNNWG23TPOBYXE43UOV3HO6DZPI')
14
+ str.string.should eql('1234567890abcdefghijklmnopqrstuvwxyz')
15
+ str.string.encoding.should eql(Encoding::BINARY)
16
+ end
17
+
18
+ it 'should treat 0 and O the same' do
19
+ str1 = Junkfood::Base32.decode('000000000')
20
+ str2 = Junkfood::Base32.decode('oooOoooOo')
21
+ str1.string.should eql(str2.string)
22
+ end
23
+
24
+ it 'should treat 1 and i the same' do
25
+ str1 = Junkfood::Base32.decode('111111111')
26
+ str2 = Junkfood::Base32.decode('iiiiIIIII')
27
+ str1.string.should eql(str2.string)
28
+ end
29
+
30
+ it 'should ignore case' do
31
+ str1 = Junkfood::Base32.decode('12345670abcdefghijklmnopqrstuvwxyz')
32
+ str2 = Junkfood::Base32.decode('12345670ABCDEFGHIJKLMNOPQRSTUVWXYZ')
33
+ str1.string.should eql(str2.string)
34
+ end
35
+
36
+ it 'should have optional splitlines'
37
+
38
+ it 'should have splitlines at specified lengths'
39
+ end
@@ -0,0 +1,73 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe 'Ceb::BaseCommand' do
4
+ before :all do
5
+ @test_class = Class.new(::Junkfood::Ceb::BaseCommand)
6
+ @test_instance = @test_class.new
7
+ @test_instance.origin = 'urn:user_id:1234'
8
+ end
9
+
10
+ it 'should respond to new_record?' do
11
+ @test_instance.respond_to?(:new_record?).should be_true
12
+ end
13
+
14
+ it 'should respond to save!' do
15
+ @test_instance.respond_to?(:save!).should be_true
16
+ end
17
+
18
+ it 'should respond to valid?' do
19
+ @test_instance.respond_to?(:valid?).should be_true
20
+ end
21
+
22
+ it 'should have id attribute' do
23
+ @test_instance.respond_to?(:id).should be_true
24
+ end
25
+
26
+ it 'should have created_at attribute' do
27
+ @test_instance.respond_to?(:created_at).should be_true
28
+ end
29
+
30
+ it 'should have origin attribute' do
31
+ @test_instance.respond_to?(:origin).should be_true
32
+ end
33
+
34
+ it 'may have events' do
35
+ # NOTE: This is not a hard requirement. We mainly want the coupling
36
+ # to be looser. It's sufficient for Events to link to Commands,
37
+ # and not necesarily need Commands to map to all of its Events.
38
+ # This test is here because we have a Mongoid MongoDb implementation.
39
+ @test_instance.respond_to?(:events).should be_true
40
+ end
41
+
42
+ it 'should respond to to_json' do
43
+ @test_instance.respond_to?(:to_json).should be_true
44
+ end
45
+
46
+ it 'json should have _id attribute' do
47
+ json_data = @test_instance.to_json
48
+ json_hash = JSON.parse json_data
49
+ json_hash.key?('_id').should be_true
50
+ end
51
+
52
+ it 'json should have _type attribute' do
53
+ json_data = @test_instance.to_json
54
+ json_hash = JSON.parse json_data
55
+ json_hash.key?('_type').should be_true
56
+ end
57
+
58
+ it 'json should have created_at attribute' do
59
+ json_data = @test_instance.to_json
60
+ json_hash = JSON.parse json_data
61
+ json_hash.key?('created_at').should be_true
62
+ end
63
+
64
+ it 'json should have origin attribute' do
65
+ json_data = @test_instance.to_json
66
+ json_hash = JSON.parse json_data
67
+ json_hash.key?('origin').should be_true
68
+ end
69
+
70
+ it 'should respond to perform' do
71
+ @test_instance.respond_to?(:perform).should be_true
72
+ end
73
+ end
@@ -0,0 +1,67 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe 'Ceb::BaseEvent' do
4
+
5
+ before :all do
6
+ @command_class = Class.new(::Junkfood::Ceb::BaseCommand)
7
+ @command_instance = @command_class.new
8
+ @test_class = Class.new(::Junkfood::Ceb::BaseEvent)
9
+ @test_instance = @test_class.new
10
+ @test_instance.command = @command_instance
11
+ end
12
+
13
+ it 'should respond to new_record?' do
14
+ @test_instance.respond_to?(:new_record?).should be_true
15
+ end
16
+
17
+ it 'should respond to save!' do
18
+ @test_instance.respond_to?(:save!).should be_true
19
+ end
20
+
21
+ it 'should respond to valid?' do
22
+ @test_instance.respond_to?(:valid?).should be_true
23
+ end
24
+
25
+ it 'should have id attribute' do
26
+ @test_instance.respond_to?(:id).should be_true
27
+ end
28
+
29
+ it 'should have created_at attribute' do
30
+ @test_instance.respond_to?(:created_at).should be_true
31
+ end
32
+
33
+ it 'should have command attributes' do
34
+ @test_instance.respond_to?(:command).should be_true
35
+ @test_instance.respond_to?(:command=).should be_true
36
+ @test_instance.respond_to?(:command_id).should be_true
37
+ @test_instance.respond_to?(:command_id=).should be_true
38
+ end
39
+
40
+ it 'should respond to to_json' do
41
+ @test_instance.respond_to?(:to_json).should be_true
42
+ end
43
+
44
+ it 'json should have _id attribute' do
45
+ json_data = @test_instance.to_json
46
+ json_hash = JSON.parse json_data
47
+ json_hash.key?('_id').should be_true
48
+ end
49
+
50
+ it 'json should have _type attribute' do
51
+ json_data = @test_instance.to_json
52
+ json_hash = JSON.parse json_data
53
+ json_hash.key?('_type').should be_true
54
+ end
55
+
56
+ it 'json should have created_at attribute' do
57
+ json_data = @test_instance.to_json
58
+ json_hash = JSON.parse json_data
59
+ json_hash.key?('created_at').should be_true
60
+ end
61
+
62
+ it 'json should have command_id attribute' do
63
+ json_data = @test_instance.to_json
64
+ json_hash = JSON.parse json_data
65
+ json_hash.key?('command_id').should be_true
66
+ end
67
+ end
@@ -0,0 +1,153 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe 'Ceb::Bus' do
4
+
5
+ it 'should acts_as_bus' do
6
+ class TestFoo
7
+ def initialize(valid)
8
+ @valid = valid
9
+ end
10
+ def valid?
11
+ @valid
12
+ end
13
+ end
14
+
15
+ # Test that we have the proper attributes and methods created with defaults.
16
+ controller_class = Class.new do
17
+ include Junkfood::Ceb::Bus
18
+ acts_as_bus :foo
19
+ end
20
+ controller_instance = controller_class.new
21
+ controller_instance.respond_to?(:send_foo).should be_true
22
+ controller_instance.respond_to?(:foo_executor).should be_true
23
+ controller_instance.respond_to?(:foo_executor=).should be_true
24
+ controller_instance.foo_executor.should be_kind_of(Proc)
25
+
26
+ # Now override the executor on the initialization
27
+ my_executor = mock('MyExecutor')
28
+ controller_class = Class.new do
29
+ include Junkfood::Ceb::Bus
30
+ acts_as_bus :foo, my_executor
31
+ end
32
+ controller_instance = controller_class.new
33
+ controller_instance.respond_to?(:send_foo).should be_true
34
+ controller_instance.respond_to?(:foo_executor).should be_true
35
+ controller_instance.respond_to?(:foo_executor=).should be_true
36
+ controller_instance.foo_executor.should eql(my_executor)
37
+
38
+ # Now test that we can override the executor, and that the
39
+ # bus creates and executes with an instane of the TestCommand
40
+ executor1 = mock('FooExecutor')
41
+ executor1.should_receive(:call).with(an_instance_of(TestFoo))
42
+ controller_instance.foo_executor = executor1
43
+ controller_instance.foo_executor.should eql(executor1)
44
+ controller_instance.send_foo 'test', true
45
+
46
+ # Now we make sure that the TestCommand is invalid, so the
47
+ # executor will not be called.
48
+ executor2 = mock('FooExecutor')
49
+ controller_instance.foo_executor = executor2
50
+ controller_instance.foo_executor.should eql(executor2)
51
+ controller_instance.send_foo 'test', false
52
+ end
53
+
54
+ it 'should acts_as_command_bus' do
55
+ class TestCommand
56
+ def initialize(valid)
57
+ @valid = valid
58
+ end
59
+ def valid?
60
+ @valid
61
+ end
62
+ end
63
+
64
+ # Test that we have the proper attributes and methods created
65
+ controller_class = Class.new do
66
+ include Junkfood::Ceb::Bus
67
+ acts_as_command_bus
68
+ end
69
+ controller_instance = controller_class.new
70
+ controller_instance.respond_to?(:send_command).should be_true
71
+ controller_instance.respond_to?(:command_executor).should be_true
72
+ controller_instance.respond_to?(:command_executor=).should be_true
73
+ controller_instance.command_executor.should be_kind_of(
74
+ Junkfood::Ceb::Executors::CommandExecutor)
75
+
76
+ # Test again that we have the proper attributes and methods created
77
+ my_executor = mock('MyExecutor')
78
+ controller_class = Class.new do
79
+ include Junkfood::Ceb::Bus
80
+ acts_as_command_bus my_executor
81
+ end
82
+ controller_instance = controller_class.new
83
+ controller_instance.respond_to?(:send_command).should be_true
84
+ controller_instance.respond_to?(:command_executor).should be_true
85
+ controller_instance.respond_to?(:command_executor=).should be_true
86
+ controller_instance.command_executor.should eql(my_executor)
87
+
88
+ # Now test that we can override the executor, and that the
89
+ # bus creates and executes with an instane of the TestCommand
90
+ executor1 = mock('CommandExecutor')
91
+ executor1.should_receive(:call).with(an_instance_of(TestCommand))
92
+ controller_instance.command_executor = executor1
93
+ controller_instance.command_executor.should eql(executor1)
94
+ controller_instance.send_command 'test', true
95
+
96
+ # Now we make sure that the TestCommand is invalid, so the
97
+ # executor will not be called.
98
+ executor2 = mock('CommandExecutor')
99
+ controller_instance.command_executor = executor2
100
+ controller_instance.command_executor.should eql(executor2)
101
+ controller_instance.send_command 'test', false
102
+ end
103
+
104
+ it 'should acts_as_event_bus' do
105
+ class TestEvent
106
+ def initialize(valid)
107
+ @valid = valid
108
+ end
109
+ def valid?
110
+ @valid
111
+ end
112
+ end
113
+
114
+ # Test that we have the proper attributes and methods created
115
+ controller_class = Class.new do
116
+ include Junkfood::Ceb::Bus
117
+ acts_as_event_bus
118
+ end
119
+ controller_instance = controller_class.new
120
+ controller_instance.respond_to?(:send_event).should be_true
121
+ controller_instance.respond_to?(:event_executor).should be_true
122
+ controller_instance.respond_to?(:event_executor=).should be_true
123
+ controller_instance.event_executor.should be_kind_of(
124
+ Junkfood::Ceb::Executors::EventExecutor)
125
+
126
+ # Test again that we have the proper attributes and methods created
127
+ my_executor = mock('MyExecutor')
128
+ controller_class = Class.new do
129
+ include Junkfood::Ceb::Bus
130
+ acts_as_event_bus my_executor
131
+ end
132
+ controller_instance = controller_class.new
133
+ controller_instance.respond_to?(:send_event).should be_true
134
+ controller_instance.respond_to?(:event_executor).should be_true
135
+ controller_instance.respond_to?(:event_executor=).should be_true
136
+ controller_instance.event_executor.should eql(my_executor)
137
+
138
+ # Now test that we can override the executor, and that the
139
+ # bus creates and executes with an instane of the TestEvent
140
+ executor1 = mock('EventExecutor')
141
+ executor1.should_receive(:call).with(an_instance_of(TestEvent))
142
+ controller_instance.event_executor = executor1
143
+ controller_instance.event_executor.should eql(executor1)
144
+ controller_instance.send_event 'test', true
145
+
146
+ # Now we make sure that the TestEvent is invalid, so the
147
+ # executor will not be called.
148
+ executor2 = mock('EventExecutor')
149
+ controller_instance.event_executor = executor2
150
+ controller_instance.event_executor.should eql(executor2)
151
+ controller_instance.send_event 'test', false
152
+ end
153
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe 'Ceb::Executors::CommandExecutor' do
4
+ it 'should save and perform the command (and return results)' do
5
+ expected_result = 'arbitrary return values'
6
+ command = mock('MyCommand')
7
+ command.should_receive(:new_record?).once.and_return(true)
8
+ command.should_receive(:save!).once
9
+ command.should_receive(:perform).once.and_return(expected_result)
10
+ executor = ::Junkfood::Ceb::Executors::CommandExecutor.new
11
+ result = executor.call command
12
+ result.should eql(expected_result)
13
+ end
14
+
15
+ it 'should just perform the command (and return results) without saving' do
16
+ expected_result = 'arbitrary return values'
17
+ command = mock('MyCommand')
18
+ command.should_receive(:new_record?).once.and_return(false)
19
+ command.should_receive(:perform).once.and_return(expected_result)
20
+ executor = ::Junkfood::Ceb::Executors::CommandExecutor.new
21
+ result = executor.call command
22
+ result.should eql(expected_result)
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe 'Ceb::Executors::DelayedJobCommandExecutor' do
4
+ it 'should just queue the command into delayed job'
5
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe 'Ceb::Executors::EventExecutor' do
4
+ it 'should save event (new record)' do
5
+ event = mock('MyEvent')
6
+ event.should_receive(:new_record?).once.and_return(true)
7
+ event.should_receive(:save!).once
8
+ executor = ::Junkfood::Ceb::Executors::EventExecutor.new
9
+ executor.call event
10
+ end
11
+
12
+ it 'should not save event (not new record)' do
13
+ event = mock('Event')
14
+ event.should_receive(:new_record?).once.and_return(false)
15
+ executor = ::Junkfood::Ceb::Executors::EventExecutor.new
16
+ executor.call event
17
+ end
18
+ end
@@ -0,0 +1,167 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "OneTime" do
4
+
5
+ it 'should pass RFC 4226 Appendix D Test Values' do
6
+ # Validates the first 10 OTPs for the RFC's test HOTP key (in RFC4226).
7
+ key = '12345678901234567890'
8
+ expected_results = [
9
+ '755224',
10
+ '287082',
11
+ '359152',
12
+ '969429',
13
+ '338314',
14
+ '254676',
15
+ '287922',
16
+ '162583',
17
+ '399871',
18
+ '520489',
19
+ ]
20
+ for x in 0..9
21
+ Junkfood::OneTime.hotp(key, x).should eql(expected_results[x])
22
+ end
23
+ end
24
+
25
+ it 'should bulk pass RFC 4226 Appendix D Test Values' do
26
+ # Validates the first 10 OTPs for the RFC's test HOTP key (in RFC4226).
27
+ key = '12345678901234567890'
28
+ expected_results = [
29
+ '755224',
30
+ '287082',
31
+ '359152',
32
+ '969429',
33
+ '338314',
34
+ '254676',
35
+ '287922',
36
+ '162583',
37
+ '399871',
38
+ '520489',
39
+ ]
40
+ results = Junkfood::OneTime.hotp_multi(
41
+ key,
42
+ 0...expected_results.size)
43
+ results.should eql(expected_results)
44
+ end
45
+
46
+ it 'should provide low level details about algorithm values' do
47
+ key = '12345678901234567890'
48
+ expected_results = [
49
+ ['755224', 1284755224, 'cc93cf18508d94934c64b65d8ba7667fb7cde4b0'],
50
+ ['287082', 1094287082, '75a48a19d4cbe100644e8ac1397eea747a2d33ab'],
51
+ ['359152', 137359152, '0bacb7fa082fef30782211938bc1c5e70416ff44'],
52
+ ['969429', 1726969429, '66c28227d03a2d5529262ff016a1e6ef76557ece'],
53
+ ['338314', 1640338314, 'a904c900a64b35909874b33e61c5938a8e15ed1c'],
54
+ ['254676', 868254676, 'a37e783d7b7233c083d4f62926c7a25f238d0316'],
55
+ ['287922', 1918287922, 'bc9cd28561042c83f219324d3c607256c03272ae'],
56
+ ['162583', 82162583, 'a4fb960c0bc06e1eabb804e5b397cdc4b45596fa'],
57
+ ['399871', 673399871, '1b3c89f65e6c9e883012052823443f048b4332db'],
58
+ ['520489', 645520489, '1637409809a679dc698207310c8c7fc07290d9e5']
59
+ ]
60
+ for counter in 0...(expected_results.size)
61
+ results = Junkfood::OneTime.hotp_raw(key, counter)
62
+ results.size.should eql(3)
63
+ # Our hmac digest is a binary string, but we want to convert it into
64
+ # readable hex strings that we have in this spec's expected results.
65
+ results[2] = results[2].unpack('H*').first
66
+ results.should eql(expected_results[counter])
67
+ end
68
+ end
69
+
70
+ it 'should start counter at 0' do
71
+ key = '12345678901234567890'
72
+ one_time = Junkfood::OneTime.new key
73
+ one_time.counter.should eql(0)
74
+ end
75
+
76
+ it 'otp method should generate values without advancing counter' do
77
+ key = '12345678901234567890'
78
+ one_time = Junkfood::OneTime.new key
79
+ first = one_time.otp
80
+ first.should eql('755224')
81
+ second = one_time.otp
82
+ second.should eql('755224')
83
+ one_time.counter.should eql(0)
84
+ end
85
+
86
+ it 'bulk otp method should generate values without advancing counter' do
87
+ key = '12345678901234567890'
88
+ one_time = Junkfood::OneTime.new key
89
+ first = one_time.otp :range => 2
90
+ first.should eql(['755224', '287082'])
91
+ one_time.counter.should eql(0)
92
+ end
93
+
94
+ it 'otp! method should advance counter' do
95
+ key = '12345678901234567890'
96
+ one_time = Junkfood::OneTime.new key
97
+ first = one_time.otp!
98
+ first.should eql('755224')
99
+ one_time.counter.should eql(1)
100
+ second = one_time.otp!
101
+ second.should eql('287082')
102
+ one_time.counter.should eql(2)
103
+ end
104
+
105
+ it 'bulk otp! method should advance counter' do
106
+ key = '12345678901234567890'
107
+ one_time = Junkfood::OneTime.new key
108
+ first = one_time.otp! :range => 2
109
+ first.should eql(['755224', '287082'])
110
+ one_time.counter.should eql(2)
111
+ end
112
+
113
+ it 'should generate counter from epoch for Time Based HOTP' do
114
+ # RFC:
115
+ # TOTP: Time-based One-time Password Algorithm
116
+
117
+ # Test time values taken from the TOTP RFC Draft 5, Appendix B
118
+ Junkfood::OneTime.epoch_counter(
119
+ :time => 59,
120
+ :step_size => 30).should eql(1)
121
+ Junkfood::OneTime.epoch_counter(
122
+ :time => 1111111109,
123
+ :step_size => 30).should eql(37037036)
124
+ Junkfood::OneTime.epoch_counter(
125
+ :time => 1111111111,
126
+ :step_size => 30).should eql(37037037)
127
+ Junkfood::OneTime.epoch_counter(
128
+ :time => 1234567890,
129
+ :step_size => 30).should eql(41152263)
130
+ Junkfood::OneTime.epoch_counter(
131
+ :time => 2000000000,
132
+ :step_size => 30).should eql(66666666)
133
+
134
+ # Now using the implicit default step size
135
+ Junkfood::OneTime::DEFAULT_STEP_SIZE.should eql(30)
136
+ Junkfood::OneTime.epoch_counter(
137
+ :time => 59).should eql(1)
138
+ Junkfood::OneTime.epoch_counter(
139
+ :time => 1111111109).should eql(37037036)
140
+ Junkfood::OneTime.epoch_counter(
141
+ :time => 1111111111).should eql(37037037)
142
+ Junkfood::OneTime.epoch_counter(
143
+ :time => 1234567890).should eql(41152263)
144
+ Junkfood::OneTime.epoch_counter(
145
+ :time => 2000000000).should eql(66666666)
146
+
147
+ # Testing alternate step sizes
148
+ Junkfood::OneTime.epoch_counter(
149
+ :time => 59,
150
+ :step_size => 60).should eql(0)
151
+ Junkfood::OneTime.epoch_counter(
152
+ :time => 59,
153
+ :step_size => 15).should eql(3)
154
+ Junkfood::OneTime.epoch_counter(
155
+ :time => 59,
156
+ :step_size => 59).should eql(1)
157
+ Junkfood::OneTime.epoch_counter(
158
+ :time => 59,
159
+ :step_size => 1).should eql(59)
160
+ Junkfood::OneTime.epoch_counter(
161
+ :time => 59,
162
+ :step_size => 2).should eql(29)
163
+ Junkfood::OneTime.epoch_counter(
164
+ :time => 2000000000,
165
+ :step_size => 15).should eql(133333333)
166
+ end
167
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe 'PaperclipStringIO' do
4
+
5
+ it 'should be a subclass of StringIO' do
6
+ io = Junkfood::PaperclipStringIo.new ''
7
+ io.kind_of?(StringIO).should eql(true)
8
+ end
9
+
10
+ it 'should have the content_type attribute' do
11
+ io = Junkfood::PaperclipStringIo.new ''
12
+ io.respond_to? :content_type
13
+ end
14
+
15
+ it 'should have the original_filename attribute' do
16
+ io = Junkfood::PaperclipStringIo.new ''
17
+ io.respond_to? :original_filename
18
+ end
19
+
20
+ it 'should have default content_type attribute' do
21
+ io = Junkfood::PaperclipStringIo.new ''
22
+ io.content_type.should eql('application/octet-stream')
23
+ end
24
+
25
+ it 'should have default original_filename attribute' do
26
+ io = Junkfood::PaperclipStringIo.new ''
27
+ io.original_filename.should eql('unnamed')
28
+ end
29
+
30
+ it 'should be able to have overridden attributes' do
31
+ filename = 'test.png'
32
+ content_type = 'image/png'
33
+ io = Junkfood::PaperclipStringIo.new(
34
+ '',
35
+ :content_type => content_type,
36
+ :filename => filename)
37
+ io.content_type.should eql(content_type)
38
+ io.original_filename.should eql(filename)
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe 'Settings' do
4
+
5
+ it 'should eventually be testable'
6
+
7
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Junkfood" do
4
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler'
2
+ begin
3
+ Bundler.setup(:default, :development)
4
+ rescue Bundler::BundlerError => e
5
+ $stderr.puts e.message
6
+ $stderr.puts "Run `bundle install` to install missing gems"
7
+ exit e.status_code
8
+ end
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ require 'junkfood'
12
+ require 'rspec/core'
13
+
14
+ # Requires supporting files with custom matchers and macros, etc,
15
+ # in ./support/ and its subdirectories.
16
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
17
+
18
+ RSpec.configure do |config|
19
+
20
+ end