alephant 0.0.9.8-java → 0.0.9.9-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/alephant.rb +4 -11
- data/lib/alephant/models/sequence_table.rb +99 -0
- data/lib/alephant/models/sequencer.rb +38 -68
- data/lib/alephant/version.rb +1 -1
- data/lib/env.rb +2 -0
- data/spec/alephant_spec.rb +16 -21
- data/spec/logger_spec.rb +1 -1
- data/spec/sequencer_spec.rb +76 -93
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 756986d1dd5f6db8d9dd0f75d26432af435bc915
|
4
|
+
data.tar.gz: 05a8a13c5c52efd12ae21744bbd2dd9aa1cc1f93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53dbcfce2dfc411d514a519f1ef805aeccbb4cd8ec97f72c5c79b05a95872932779b7699dd208c0a5234c20747895d858dab3c74388a4b1a048088dd98e81a36
|
7
|
+
data.tar.gz: 8edf5c153d6da5691657ca275ce3b2b6e4960641be4e9e731edea571a60f88fd267b9dc25ef3e076930229eb414ed80b0e4ad391c474e31475b3411ac20284a0
|
data/lib/alephant.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
|
3
1
|
require_relative 'env'
|
4
2
|
|
5
3
|
require 'alephant/models/logger'
|
@@ -7,6 +5,7 @@ require 'alephant/models/queue'
|
|
7
5
|
require 'alephant/models/cache'
|
8
6
|
require 'alephant/models/renderer'
|
9
7
|
require 'alephant/models/multi_renderer'
|
8
|
+
require 'alephant/models/sequence_table'
|
10
9
|
require 'alephant/models/sequencer'
|
11
10
|
require 'alephant/models/parser'
|
12
11
|
|
@@ -33,13 +32,7 @@ module Alephant
|
|
33
32
|
set_opts(opts)
|
34
33
|
|
35
34
|
@logger = ::Alephant.logger
|
36
|
-
@sequencer = Sequencer.
|
37
|
-
{
|
38
|
-
:table_name => @table_name
|
39
|
-
},
|
40
|
-
@sqs_queue_id
|
41
|
-
)
|
42
|
-
|
35
|
+
@sequencer = Sequencer.create(@table_name, @sqs_queue_id, @sequence_id)
|
43
36
|
@queue = Queue.new(@sqs_queue_id)
|
44
37
|
@cache = Cache.new(@s3_bucket_id, @s3_object_path)
|
45
38
|
@multi_renderer = MultiRenderer.new(@component_id, @view_path)
|
@@ -59,9 +52,9 @@ module Alephant
|
|
59
52
|
def receive(msg)
|
60
53
|
@logger.info("Alephant.receive: with id #{msg.id} and body digest: #{msg.md5}")
|
61
54
|
|
62
|
-
if @sequencer.sequential?(msg
|
55
|
+
if @sequencer.sequential?(msg)
|
63
56
|
write @parser.parse msg.body
|
64
|
-
@sequencer.set_last_seen(msg
|
57
|
+
@sequencer.set_last_seen(msg)
|
65
58
|
else
|
66
59
|
@logger.warn("Alephant.receive: out of sequence message received #{msg.id} (discarded)")
|
67
60
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'thread'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
module Alephant
|
6
|
+
module Sequencer
|
7
|
+
class SequenceTable
|
8
|
+
attr_reader :table_name
|
9
|
+
|
10
|
+
TIMEOUT = 120
|
11
|
+
DEFAULT_CONFIG = {
|
12
|
+
:write_units => 5,
|
13
|
+
:read_units => 10,
|
14
|
+
}
|
15
|
+
SCHEMA = {
|
16
|
+
:hash_key => {
|
17
|
+
:key => :string,
|
18
|
+
:value => :string
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
def initialize(table_name, config = DEFAULT_CONFIG)
|
23
|
+
@mutex = Mutex.new
|
24
|
+
@dynamo_db = AWS::DynamoDB.new
|
25
|
+
@table_name = table_name
|
26
|
+
@config = config
|
27
|
+
end
|
28
|
+
|
29
|
+
def create
|
30
|
+
@mutex.synchronize do
|
31
|
+
ensure_table_exists
|
32
|
+
ensure_table_active
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def table
|
37
|
+
@table ||= @dynamo_db.tables[@table_name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def sequence_for(ident)
|
41
|
+
rows = batch_get_value_for(ident)
|
42
|
+
rows.count >= 1 ? rows.first['value'].to_i : 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_sequence_for(ident,value)
|
46
|
+
@mutex.synchronize do
|
47
|
+
AWS::DynamoDB::BatchWrite.new.tap { |batch|
|
48
|
+
batch.put(
|
49
|
+
table_name,
|
50
|
+
[:key => ident,:value => value]
|
51
|
+
)
|
52
|
+
}.process!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete_item!(ident)
|
57
|
+
table.items[ident].delete
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def batch_get_value_for(ident)
|
62
|
+
table.batch_get(['value'],[ident],batch_get_opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
def batch_get_opts
|
66
|
+
{ :consistent_read => true }
|
67
|
+
end
|
68
|
+
|
69
|
+
def ensure_table_exists
|
70
|
+
create_dynamodb_table unless table.exists?
|
71
|
+
end
|
72
|
+
|
73
|
+
def ensure_table_active
|
74
|
+
sleep_until_table_active unless table_active?
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_dynamodb_table
|
78
|
+
@table = @dynamo_db.tables.create(
|
79
|
+
@table_name,
|
80
|
+
@config[:read_units],
|
81
|
+
@config[:write_units],
|
82
|
+
SCHEMA
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def table_active?
|
87
|
+
table.status == :active
|
88
|
+
end
|
89
|
+
|
90
|
+
def sleep_until_table_active
|
91
|
+
begin
|
92
|
+
Timeout::timeout(TIMEOUT) do
|
93
|
+
sleep 1 until table_active?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,91 +1,61 @@
|
|
1
|
-
require 'aws-sdk'
|
2
1
|
require 'jsonpath'
|
3
2
|
|
4
3
|
module Alephant
|
5
|
-
|
6
|
-
|
4
|
+
module Sequencer
|
5
|
+
@@sequence_tables = {}
|
7
6
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
:read_units => 10,
|
12
|
-
:schema => {
|
13
|
-
:hash_key => {
|
14
|
-
:key => :string,
|
15
|
-
:value => :string
|
16
|
-
}
|
17
|
-
}
|
18
|
-
}
|
7
|
+
def self.create(table_name, ident, jsonpath = nil)
|
8
|
+
@@sequence_tables[table_name] ||= SequenceTable.new(table_name)
|
9
|
+
Sequencer.new(@@sequence_tables[table_name], ident, jsonpath)
|
19
10
|
end
|
20
11
|
|
21
|
-
|
22
|
-
|
12
|
+
class Sequencer
|
13
|
+
attr_reader :ident, :jsonpath
|
23
14
|
|
24
|
-
|
15
|
+
def initialize(sequence_table, id, sequence_path = nil)
|
16
|
+
@mutex = Mutex.new
|
17
|
+
@sequence_table = sequence_table
|
18
|
+
@jsonpath = sequence_path
|
19
|
+
@ident = id
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@table = dynamo_db.tables[@table_name]
|
30
|
-
|
31
|
-
begin
|
32
|
-
sleep_until_table_active
|
33
|
-
rescue AWS::DynamoDB::Errors::ResourceNotFoundException
|
34
|
-
@logger.error("Sequencer.initialize: DynamoDB resource was not found.")
|
35
|
-
|
36
|
-
@table = dynamo_db.tables.create(
|
37
|
-
@table_name,
|
38
|
-
@table_conf[:read_units],
|
39
|
-
@table_conf[:write_units],
|
40
|
-
@table_conf[:schema]
|
41
|
-
)
|
21
|
+
::Alephant.logger.info("Sequencer.initialize: with id #{@ident}")
|
22
|
+
@sequence_table.create
|
23
|
+
end
|
42
24
|
|
43
|
-
|
25
|
+
def sequential?(data)
|
26
|
+
get_last_seen < sequence_id_from(data)
|
27
|
+
end
|
44
28
|
|
45
|
-
|
29
|
+
def delete!
|
30
|
+
@sequence_table.delete_item!(ident)
|
46
31
|
end
|
47
32
|
|
48
|
-
|
49
|
-
|
33
|
+
def set_last_seen(data)
|
34
|
+
last_seen_id = sequence_id_from(data)
|
50
35
|
|
51
|
-
|
52
|
-
|
53
|
-
|
36
|
+
@sequence_table.set_sequence_for(ident, last_seen_id)
|
37
|
+
::Alephant.logger.info("Sequencer.set_last_seen: #{ident}:#{last_seen_id}")
|
38
|
+
end
|
54
39
|
|
55
|
-
|
56
|
-
|
40
|
+
def get_last_seen
|
41
|
+
@sequence_table.sequence_for(ident)
|
42
|
+
end
|
57
43
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
44
|
+
private
|
45
|
+
def sequence_id_from(data)
|
46
|
+
jsonpath.nil? ?
|
47
|
+
default_sequence_id_for(data) :
|
48
|
+
sequence_from_jsonpath_for(data)
|
49
|
+
end
|
63
50
|
|
64
|
-
|
65
|
-
jsonpath.nil? ?
|
66
|
-
data.body['sequence_id'].to_i :
|
51
|
+
def sequence_from_jsonpath_for(data)
|
67
52
|
JsonPath.on(data.body, jsonpath).first
|
68
|
-
|
53
|
+
end
|
69
54
|
|
70
|
-
|
71
|
-
|
72
|
-
@table.batch_get(
|
73
|
-
['value'],
|
74
|
-
[@id],
|
75
|
-
{
|
76
|
-
:consistent_read => true
|
77
|
-
}
|
78
|
-
).first["value"].to_i
|
79
|
-
rescue Exception => e
|
80
|
-
trace = e.backtrace.join('\n')
|
81
|
-
@logger.error("Sequencer.get_last_seen: id #{id}\nmessage: #{e.message}\ntrace: #{trace}")
|
82
|
-
0
|
55
|
+
def default_sequence_id_for(data)
|
56
|
+
data.body['sequence_id'].to_i
|
83
57
|
end
|
84
|
-
end
|
85
58
|
|
86
|
-
def sleep_until_table_active
|
87
|
-
sleep 1 until @table.status == :active
|
88
59
|
end
|
89
|
-
|
90
60
|
end
|
91
61
|
end
|
data/lib/alephant/version.rb
CHANGED
data/lib/env.rb
CHANGED
data/spec/alephant_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe Alephant::Alephant do
|
|
10
10
|
cache = double()
|
11
11
|
multi_renderer = double()
|
12
12
|
|
13
|
-
Alephant::Sequencer.
|
13
|
+
Alephant::Sequencer.stub(:create).and_return(sequencer)
|
14
14
|
Alephant::Queue.any_instance.stub(:initialize).and_return(queue)
|
15
15
|
Alephant::Cache.any_instance.stub(:initialize).and_return(cache)
|
16
16
|
Alephant::MultiRenderer.any_instance.stub(:initialize).and_return(multi_renderer)
|
@@ -49,14 +49,15 @@ describe Alephant::Alephant do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
context "initializes @sequencer" do
|
52
|
-
it "with Sequencer.
|
52
|
+
it "with Sequencer.create(:table_name, @sqs_queue_id)" do
|
53
53
|
Alephant::Sequencer
|
54
|
-
.should_receive(:
|
55
|
-
.with(
|
54
|
+
.should_receive(:create)
|
55
|
+
.with(:table_name, :sqs_queue_id, :sequence_id)
|
56
56
|
|
57
57
|
instance = subject.new({
|
58
58
|
:table_name => :table_name,
|
59
|
-
:sqs_queue_id => :sqs_queue_id
|
59
|
+
:sqs_queue_id => :sqs_queue_id,
|
60
|
+
:sequence_id => :sequence_id
|
60
61
|
})
|
61
62
|
end
|
62
63
|
end
|
@@ -107,7 +108,7 @@ describe Alephant::Alephant do
|
|
107
108
|
cache = double()
|
108
109
|
multi_renderer = double()
|
109
110
|
|
110
|
-
Alephant::Sequencer.
|
111
|
+
Alephant::Sequencer.stub(:create).and_return(sequencer)
|
111
112
|
Alephant::Queue.any_instance.stub(:initialize).and_return(queue)
|
112
113
|
Alephant::Cache.any_instance.stub(:initialize).and_return(cache)
|
113
114
|
Alephant::MultiRenderer.any_instance.stub(:initialize).and_return(multi_renderer)
|
@@ -144,22 +145,11 @@ describe Alephant::Alephant do
|
|
144
145
|
cache = double()
|
145
146
|
multi_renderer = double()
|
146
147
|
|
147
|
-
Alephant::Sequencer.any_instance.stub(:initialize).and_return(sequencer)
|
148
148
|
Alephant::Queue.any_instance.stub(:initialize).and_return(queue)
|
149
149
|
Alephant::Cache.any_instance.stub(:initialize).and_return(cache)
|
150
150
|
Alephant::MultiRenderer.any_instance.stub(:initialize).and_return(multi_renderer)
|
151
151
|
end
|
152
152
|
|
153
|
-
it "takes json as an argument" do
|
154
|
-
instance = subject.new
|
155
|
-
|
156
|
-
msg = double()
|
157
|
-
msg.stub(:body).and_return('notjson')
|
158
|
-
|
159
|
-
expect { JsonPath.on(msg.body, '$.foo') }
|
160
|
-
.to raise_error(MultiJson::LoadError);
|
161
|
-
end
|
162
|
-
|
163
153
|
it "writes data to cache if sequential order is true" do
|
164
154
|
data = "{ \"foo\":\"bar\" }"
|
165
155
|
|
@@ -168,17 +158,22 @@ describe Alephant::Alephant do
|
|
168
158
|
msg.stub(:md5).and_return(:md5)
|
169
159
|
msg.stub(:body).and_return(data)
|
170
160
|
|
171
|
-
instance = subject.new
|
172
161
|
|
173
|
-
Alephant::Sequencer
|
162
|
+
Alephant::Sequencer::Sequencer
|
174
163
|
.any_instance
|
175
164
|
.stub(:sequential?)
|
176
165
|
.and_return(true)
|
177
166
|
|
178
|
-
Alephant::Sequencer
|
167
|
+
Alephant::Sequencer::SequenceTable
|
168
|
+
.any_instance
|
169
|
+
.stub(:create)
|
170
|
+
|
171
|
+
Alephant::Sequencer::Sequencer
|
179
172
|
.any_instance
|
180
173
|
.stub(:set_last_seen)
|
181
174
|
|
175
|
+
instance = subject.new
|
176
|
+
|
182
177
|
instance
|
183
178
|
.should_receive(:write)
|
184
179
|
.with(JSON.parse(data, :symbolize_names => true))
|
@@ -192,7 +187,7 @@ describe Alephant::Alephant do
|
|
192
187
|
sequencer = double()
|
193
188
|
queue = double()
|
194
189
|
|
195
|
-
Alephant::Sequencer
|
190
|
+
Alephant::Sequencer::Sequencer
|
196
191
|
.any_instance
|
197
192
|
.stub(:initialize)
|
198
193
|
.and_return(sequencer)
|
data/spec/logger_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Alephant::LogSystem do
|
|
7
7
|
cache = double()
|
8
8
|
renderer = double()
|
9
9
|
|
10
|
-
Alephant::Sequencer.
|
10
|
+
Alephant::Sequencer.stub(:create).and_return(sequencer)
|
11
11
|
Alephant::Queue.any_instance.stub(:initialize).and_return(queue)
|
12
12
|
Alephant::Cache.any_instance.stub(:initialize).and_return(cache)
|
13
13
|
Alephant::Renderer.any_instance.stub(:initialize).and_return(renderer)
|
data/spec/sequencer_spec.rb
CHANGED
@@ -1,124 +1,107 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Alephant::Sequencer do
|
4
|
-
subject { Alephant::Sequencer }
|
5
3
|
|
6
|
-
|
4
|
+
describe Alephant::Sequencer do
|
5
|
+
let(:ident) { :ident }
|
6
|
+
let(:jsonpath) { :jsonpath }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
describe ".create(table_name, ident, jsonpath)" do
|
9
|
+
it "should return a Sequencer" do
|
10
|
+
Alephant::Sequencer::SequenceTable.any_instance.stub(:create)
|
11
|
+
expect(subject.create(:table_name, ident, jsonpath)).to be_a Alephant::Sequencer::Sequencer
|
12
|
+
end
|
13
|
+
end
|
14
14
|
|
15
|
-
|
15
|
+
describe Alephant::Sequencer::Sequencer do
|
16
|
+
let(:data) { double() }
|
17
|
+
let(:last_seen) { 42 }
|
18
|
+
let(:sequence_table) { double().tap { |o| o.stub(:create) } }
|
19
|
+
subject { Alephant::Sequencer::Sequencer.new(sequence_table, ident, jsonpath) }
|
20
|
+
|
21
|
+
describe "#initialize(opts, id)" do
|
22
|
+
it "sets @jsonpath, @ident" do
|
23
|
+
expect(subject.jsonpath).to eq(jsonpath)
|
24
|
+
expect(subject.ident).to eq(ident)
|
25
|
+
end
|
16
26
|
|
17
|
-
|
18
|
-
|
19
|
-
:
|
20
|
-
}, :sqs_queue_id)
|
27
|
+
it "calls create on sequence_table" do
|
28
|
+
table = double()
|
29
|
+
table.should_receive(:create)
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
expect(instance.table_conf).to eq(:table_conf)
|
31
|
+
Alephant::Sequencer::Sequencer.new(table, ident, jsonpath)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
table_collection = double()
|
40
|
-
table_collection.should_receive(:create).with(
|
41
|
-
opts[:table_name],
|
42
|
-
opts[:table_conf][:read_units],
|
43
|
-
opts[:table_conf][:write_units],
|
44
|
-
opts[:table_conf][:schema]
|
45
|
-
)
|
46
|
-
|
47
|
-
AWS::DynamoDB.any_instance.stub(:tables).and_return({},table_collection)
|
48
|
-
|
49
|
-
Alephant::Sequencer
|
50
|
-
.any_instance
|
51
|
-
.stub(:sleep_until_table_active).and_yield do
|
52
|
-
@times_called ||= 0
|
53
|
-
raise AWS::DynamoDB::Errors::ResourceNotFoundException if @times_called == 0
|
54
|
-
@times_called += 1
|
55
|
-
end
|
56
|
-
|
57
|
-
subject.new(opts, :id)
|
58
|
-
end
|
35
|
+
describe "#get_last_seen" do
|
36
|
+
it "returns sequence_table.sequence_for(ident)" do
|
37
|
+
table = double()
|
38
|
+
table.stub(:create)
|
39
|
+
table.should_receive(:sequence_for).with(ident).and_return(:expected_value)
|
40
|
+
|
41
|
+
expect(
|
42
|
+
Alephant::Sequencer::Sequencer.new(table, ident).get_last_seen
|
43
|
+
).to eq(:expected_value)
|
59
44
|
end
|
60
45
|
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "sequential?(data, jsonpath = nil)" do
|
64
|
-
let(:jsonpath) { '$.sequence_id' }
|
65
|
-
let(:instance) { subject.new }
|
66
|
-
let(:id_value) { 0 }
|
67
|
-
let(:data) { double() }
|
68
46
|
|
69
|
-
|
70
|
-
|
71
|
-
.any_instance.stub(:
|
72
|
-
|
47
|
+
describe "#set_last_seen(data)" do
|
48
|
+
before(:each) do
|
49
|
+
Alephant::Sequencer::Sequencer.any_instance.stub(:sequence_id_from).and_return(last_seen)
|
50
|
+
end
|
73
51
|
|
74
|
-
|
75
|
-
|
76
|
-
.stub(:
|
77
|
-
.
|
52
|
+
it "calls set_sequence_for(ident, last_seen)" do
|
53
|
+
table = double()
|
54
|
+
table.stub(:create)
|
55
|
+
table.should_receive(:set_sequence_for).with(ident, last_seen)
|
78
56
|
|
79
|
-
|
57
|
+
Alephant::Sequencer::Sequencer.new(table, ident).set_last_seen(data)
|
58
|
+
end
|
80
59
|
end
|
81
60
|
|
82
|
-
|
83
|
-
context "in sequence" do
|
84
|
-
let(:id_value) { 2 }
|
61
|
+
describe "#sequential?(data, jsonpath)" do
|
85
62
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
63
|
+
before(:each) do
|
64
|
+
Alephant::Sequencer::Sequencer.any_instance.stub(:get_last_seen).and_return(1)
|
65
|
+
data.stub(:body).and_return('sequence_id' => id_value)
|
90
66
|
end
|
91
67
|
|
92
|
-
context "
|
93
|
-
let(:
|
68
|
+
context "jsonpath = '$.sequence_id'" do
|
69
|
+
let(:jsonpath) { '$.sequence_id' }
|
70
|
+
subject { Alephant::Sequencer::Sequencer.new(sequence_table, :ident, jsonpath) }
|
71
|
+
context "sequential" do
|
72
|
+
let(:id_value) { 2 }
|
73
|
+
it "is true" do
|
74
|
+
expect(subject.sequential?(data)).to be_true
|
75
|
+
end
|
76
|
+
end
|
94
77
|
|
95
|
-
|
96
|
-
|
97
|
-
|
78
|
+
context "nonsequential" do
|
79
|
+
let(:id_value) { 0 }
|
80
|
+
it "is false" do
|
81
|
+
expect(subject.sequential?(data)).to be_false
|
82
|
+
end
|
98
83
|
end
|
99
84
|
end
|
100
|
-
end
|
101
85
|
|
102
|
-
|
103
|
-
|
104
|
-
|
86
|
+
context "jsonpath = nil" do
|
87
|
+
let(:jsonpath) { nil }
|
88
|
+
subject { Alephant::Sequencer::Sequencer.new(sequence_table, :ident, jsonpath) }
|
105
89
|
|
106
|
-
|
107
|
-
|
108
|
-
|
90
|
+
context "sequential" do
|
91
|
+
let(:id_value) { 2 }
|
92
|
+
it "is true" do
|
93
|
+
expect(subject.sequential?(data)).to be_true
|
94
|
+
end
|
109
95
|
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "out of sequence" do
|
113
|
-
let(:id_value) { 0 }
|
114
96
|
|
115
|
-
|
116
|
-
|
117
|
-
|
97
|
+
context "nonsequential" do
|
98
|
+
let(:id_value) { 0 }
|
99
|
+
it "is false" do
|
100
|
+
expect(subject.sequential?(data)).to be_false
|
101
|
+
end
|
118
102
|
end
|
119
103
|
end
|
120
|
-
end
|
121
104
|
|
105
|
+
end
|
122
106
|
end
|
123
107
|
end
|
124
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alephant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.9.
|
4
|
+
version: 0.0.9.9
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Robert Kenny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -234,6 +234,7 @@ files:
|
|
234
234
|
- lib/alephant/models/parser.rb
|
235
235
|
- lib/alephant/models/queue.rb
|
236
236
|
- lib/alephant/models/renderer.rb
|
237
|
+
- lib/alephant/models/sequence_table.rb
|
237
238
|
- lib/alephant/models/sequencer.rb
|
238
239
|
- lib/alephant/preview/server.rb
|
239
240
|
- lib/alephant/preview/template.rb
|