protobuf_spec 0.3.1
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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/CONTRIBUTION_GUIDELINES.md +22 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +14 -0
- data/README.md +165 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/features/builder.feature +34 -0
- data/features/equivalence.feature +95 -0
- data/features/inclusion.feature +72 -0
- data/features/memory.feature +135 -0
- data/features/paths.feature +21 -0
- data/features/step_definitions/steps.rb +3 -0
- data/features/support/env.rb +9 -0
- data/features/support/sample.pb.rb +40 -0
- data/lib/protobuf_spec.rb +4 -0
- data/lib/protobuf_spec/builder.rb +46 -0
- data/lib/protobuf_spec/cucumber.rb +69 -0
- data/lib/protobuf_spec/extensions.rb +9 -0
- data/lib/protobuf_spec/matchers.rb +18 -0
- data/lib/protobuf_spec/matchers/be_protobuf_eql.rb +37 -0
- data/lib/protobuf_spec/matchers/have_protobuf_path.rb +27 -0
- data/protobuf_spec.gemspec +87 -0
- data/sample.proto +17 -0
- data/spec/protobuf_spec/matchers/be_protobuf_eql_spec.rb +21 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/sample.pb.rb +40 -0
- metadata +151 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
Feature: Inclusion
|
2
|
+
Background:
|
3
|
+
Given I create the following ProtoBuf of type "Sample":
|
4
|
+
"""
|
5
|
+
{
|
6
|
+
"string_field": "foo",
|
7
|
+
"int_field": 5,
|
8
|
+
"double_field": 50.23,
|
9
|
+
"int_field_2": -9,
|
10
|
+
"bool_field": true,
|
11
|
+
"bool_field_2": false
|
12
|
+
}
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: String
|
16
|
+
When I get the ProtoBuf
|
17
|
+
Then the ProtoBuf should include "foo"
|
18
|
+
Then the ProtoBuf should include:
|
19
|
+
"""
|
20
|
+
"foo"
|
21
|
+
"""
|
22
|
+
|
23
|
+
Scenario: Integer
|
24
|
+
When I get the ProtoBuf
|
25
|
+
Then the ProtoBuf should include 5
|
26
|
+
And the ProtoBuf should include:
|
27
|
+
"""
|
28
|
+
5
|
29
|
+
"""
|
30
|
+
|
31
|
+
Scenario: Negative integer
|
32
|
+
When I get the ProtoBuf
|
33
|
+
Then the ProtoBuf should include -9
|
34
|
+
And the ProtoBuf should include:
|
35
|
+
"""
|
36
|
+
-9
|
37
|
+
"""
|
38
|
+
|
39
|
+
Scenario: Double
|
40
|
+
When I get the ProtoBuf
|
41
|
+
Then the ProtoBuf should include 50.23
|
42
|
+
And the ProtoBuf should include 50.23e0
|
43
|
+
And the ProtoBuf should include 50.23e+0
|
44
|
+
And the ProtoBuf should include 50.23e-0
|
45
|
+
And the ProtoBuf should include 50.23e0
|
46
|
+
And the ProtoBuf should include 50.23e+0
|
47
|
+
And the ProtoBuf should include 50.23e-0
|
48
|
+
And the ProtoBuf should include 5.023e1
|
49
|
+
And the ProtoBuf should include 5.023e+1
|
50
|
+
And the ProtoBuf should include 502.3e-1
|
51
|
+
And the ProtoBuf should include:
|
52
|
+
"""
|
53
|
+
50.23
|
54
|
+
"""
|
55
|
+
|
56
|
+
Then the ProtoBuf should not include -15.45
|
57
|
+
|
58
|
+
Scenario: True
|
59
|
+
When I get the ProtoBuf
|
60
|
+
Then the protobuf should include true
|
61
|
+
Then the protobuf should include:
|
62
|
+
"""
|
63
|
+
true
|
64
|
+
"""
|
65
|
+
|
66
|
+
Scenario: False
|
67
|
+
When I get the ProtoBuf
|
68
|
+
Then the protobuf should include false
|
69
|
+
Then the protobuf should include:
|
70
|
+
"""
|
71
|
+
false
|
72
|
+
"""
|
@@ -0,0 +1,135 @@
|
|
1
|
+
Feature: Memory
|
2
|
+
Background:
|
3
|
+
Given I create the following ProtoBuf of type "Sample":
|
4
|
+
"""
|
5
|
+
{
|
6
|
+
"string_field": "foo",
|
7
|
+
"int_field": 5,
|
8
|
+
"double_field": 50.23,
|
9
|
+
"int_field_2": -9,
|
10
|
+
"bool_field": true,
|
11
|
+
"bool_field_2": false
|
12
|
+
}
|
13
|
+
"""
|
14
|
+
And I get the Protobuf
|
15
|
+
|
16
|
+
Scenario: Entire Protobuf
|
17
|
+
When I keep the Protobuf as "PROTO"
|
18
|
+
Then the Protobuf should be %{PROTO}
|
19
|
+
And the Protobuf should be:
|
20
|
+
"""
|
21
|
+
%{PROTO}
|
22
|
+
"""
|
23
|
+
|
24
|
+
Scenario: String
|
25
|
+
When I keep the ProtoBuf at "string_field" as "STRING"
|
26
|
+
Then the ProtoBuf at "string_field" should be %{STRING}
|
27
|
+
And the ProtoBuf should be:
|
28
|
+
"""
|
29
|
+
{
|
30
|
+
"string_field": %{STRING},
|
31
|
+
"int_field": 5,
|
32
|
+
"double_field": 50.23,
|
33
|
+
"int_field_2": -9,
|
34
|
+
"bool_field": true,
|
35
|
+
"bool_field_2": false
|
36
|
+
}
|
37
|
+
"""
|
38
|
+
|
39
|
+
Scenario: Integer
|
40
|
+
When I keep the ProtoBuf at "int_field" as "INTEGER"
|
41
|
+
Then the ProtoBuf at "int_field" should be %{INTEGER}
|
42
|
+
And the ProtoBuf should be:
|
43
|
+
"""
|
44
|
+
{
|
45
|
+
"string_field": "foo",
|
46
|
+
"int_field": %{INTEGER},
|
47
|
+
"double_field": 50.23,
|
48
|
+
"int_field_2": -9,
|
49
|
+
"bool_field": true,
|
50
|
+
"bool_field_2": false
|
51
|
+
}
|
52
|
+
"""
|
53
|
+
|
54
|
+
Scenario: Double
|
55
|
+
When I keep the ProtoBuf at "double_field" as "DOUBLE"
|
56
|
+
Then the ProtoBuf at "double_field" should be %{DOUBLE}
|
57
|
+
And the ProtoBuf should be:
|
58
|
+
"""
|
59
|
+
{
|
60
|
+
"string_field": "foo",
|
61
|
+
"int_field": 5,
|
62
|
+
"double_field": %{DOUBLE},
|
63
|
+
"int_field_2": -9,
|
64
|
+
"bool_field": true,
|
65
|
+
"bool_field_2": false
|
66
|
+
}
|
67
|
+
"""
|
68
|
+
|
69
|
+
Scenario: True
|
70
|
+
When I keep the ProtoBuf at "bool_field" as "TRUE"
|
71
|
+
Then the ProtoBuf at "bool_field" should be %{TRUE}
|
72
|
+
And the ProtoBuf should be:
|
73
|
+
"""
|
74
|
+
{
|
75
|
+
"string_field": "foo",
|
76
|
+
"int_field": 5,
|
77
|
+
"double_field": 50.23,
|
78
|
+
"int_field_2": -9,
|
79
|
+
"bool_field": %{TRUE},
|
80
|
+
"bool_field_2": false
|
81
|
+
}
|
82
|
+
"""
|
83
|
+
|
84
|
+
Scenario: False
|
85
|
+
When I keep the ProtoBuf at "bool_field_2" as "FALSE"
|
86
|
+
Then the ProtoBuf at "bool_field_2" should be %{FALSE}
|
87
|
+
And the ProtoBuf should be:
|
88
|
+
"""
|
89
|
+
{
|
90
|
+
"string_field": "foo",
|
91
|
+
"int_field": 5,
|
92
|
+
"double_field": 50.23,
|
93
|
+
"int_field_2": -9,
|
94
|
+
"bool_field": true,
|
95
|
+
"bool_field_2": %{FALSE}
|
96
|
+
}
|
97
|
+
"""
|
98
|
+
|
99
|
+
Scenario: Table format
|
100
|
+
When I keep the ProtoBuf at "string_field" as "STRING"
|
101
|
+
And I keep the ProtoBuf at "int_field" as "INTEGER"
|
102
|
+
And I keep the ProtoBuf at "double_field" as "DOUBLE"
|
103
|
+
And I keep the ProtoBuf at "bool_field" as "TRUE"
|
104
|
+
And I keep the ProtoBuf at "bool_field_2" as "FALSE"
|
105
|
+
Then the ProtoBuf should have the following:
|
106
|
+
| string_field | %{STRING} |
|
107
|
+
| int_field | %{INTEGER} |
|
108
|
+
| double_field | %{DOUBLE} |
|
109
|
+
| bool_field | %{TRUE} |
|
110
|
+
| bool_field_2 | %{FALSE} |
|
111
|
+
|
112
|
+
Scenario: Inclusion
|
113
|
+
When I keep the ProtoBuf at "string_field" as "STRING"
|
114
|
+
And I keep the ProtoBuf at "int_field" as "INTEGER"
|
115
|
+
And I keep the ProtoBuf at "double_field" as "DOUBLE"
|
116
|
+
And I keep the ProtoBuf at "bool_field" as "TRUE"
|
117
|
+
And I keep the ProtoBuf at "bool_field_2" as "FALSE"
|
118
|
+
Then the ProtoBuf should include %{STRING}
|
119
|
+
Then the ProtoBuf should include %{INTEGER}
|
120
|
+
Then the ProtoBuf should include %{DOUBLE}
|
121
|
+
Then the ProtoBuf should include %{TRUE}
|
122
|
+
Then the ProtoBuf should include %{FALSE}
|
123
|
+
|
124
|
+
Scenario: I can store the serialized form of a protocol buffer in cuke_mem
|
125
|
+
Given I create a ProtoBuf of type "Sample"
|
126
|
+
And I set the ProtoBuf at "string_field" to "hello"
|
127
|
+
And I set the ProtoBuf at "int_field" to -5
|
128
|
+
And I set the ProtoBuf at "double_field" to 123.45
|
129
|
+
And I get the ProtoBuf
|
130
|
+
When I save the serialized ProtoBuf as "SERIALIZED"
|
131
|
+
And I deserialize a Protobuf of type "Sample" from "%{SERIALIZED}"
|
132
|
+
And I get the ProtoBuf
|
133
|
+
Then the ProtoBuf at "string_field" should be "hello"
|
134
|
+
And the ProtoBuf at "int_field" should be -5
|
135
|
+
And the ProtoBuf at "double_field" should be 123.45
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: Paths
|
2
|
+
Background:
|
3
|
+
Given I create the following ProtoBuf of type "Sample":
|
4
|
+
"""
|
5
|
+
{
|
6
|
+
"string_field": "foo",
|
7
|
+
"int_field": 5
|
8
|
+
}
|
9
|
+
"""
|
10
|
+
|
11
|
+
Scenario: Base paths
|
12
|
+
When I get the ProtoBuf
|
13
|
+
Then the ProtoBuf should have "string_field"
|
14
|
+
Then the ProtoBuf should have "int_field"
|
15
|
+
Then the ProtoBuf should not have "double_field"
|
16
|
+
|
17
|
+
Scenario: Table format
|
18
|
+
When I get the ProtoBuf
|
19
|
+
Then the ProtoBuf should have the following:
|
20
|
+
| string_field |
|
21
|
+
| int_field |
|
@@ -0,0 +1,40 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: sample.proto>
|
3
|
+
# message Sample {
|
4
|
+
# optional string string_field = 1;
|
5
|
+
# optional int32 int_field = 2;
|
6
|
+
# optional double double_field = 3;
|
7
|
+
#
|
8
|
+
# optional string string_field_2 = 4;
|
9
|
+
# optional int32 int_field_2 = 5;
|
10
|
+
# optional double double_field_2 = 6;
|
11
|
+
#
|
12
|
+
# optional string string_field_3 = 7;
|
13
|
+
# optional int32 int_field_3 = 8;
|
14
|
+
# optional double double_field_3 = 9;
|
15
|
+
#
|
16
|
+
# optional bool bool_field=10;
|
17
|
+
# optional bool bool_field_2=11;
|
18
|
+
# optional bool bool_field_3=12;
|
19
|
+
# }
|
20
|
+
|
21
|
+
require 'protobuf/message/message'
|
22
|
+
require 'protobuf/message/enum'
|
23
|
+
require 'protobuf/message/service'
|
24
|
+
require 'protobuf/message/extend'
|
25
|
+
|
26
|
+
class Sample < ::Protobuf::Message
|
27
|
+
defined_in __FILE__
|
28
|
+
optional :string, :string_field, 1
|
29
|
+
optional :int32, :int_field, 2
|
30
|
+
optional :double, :double_field, 3
|
31
|
+
optional :string, :string_field_2, 4
|
32
|
+
optional :int32, :int_field_2, 5
|
33
|
+
optional :double, :double_field_2, 6
|
34
|
+
optional :string, :string_field_3, 7
|
35
|
+
optional :int32, :int_field_3, 8
|
36
|
+
optional :double, :double_field_3, 9
|
37
|
+
optional :bool, :bool_field, 10
|
38
|
+
optional :bool, :bool_field_2, 11
|
39
|
+
optional :bool, :bool_field_3, 12
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'cuke_mem'
|
2
|
+
|
3
|
+
module ProtobufSpec
|
4
|
+
module Builder
|
5
|
+
def self.protobuf
|
6
|
+
@protobuf
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.protobuf= protobuf
|
10
|
+
@protobuf=protobuf
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
Given /^I create a (?:ProtoBuf|Protobuf|protobuf) of type "([^"]*)"$/ do |proto_type|
|
17
|
+
ProtobufSpec::Builder.protobuf = eval("#{proto_type}.new")
|
18
|
+
end
|
19
|
+
|
20
|
+
Given /^I set the (?:ProtoBuf|Protobuf|protobuf) at "([^"]*)" to "([^"]*)"$/ do |field, val|
|
21
|
+
ProtobufSpec::Builder.protobuf.send("#{field}=".to_sym, val)
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /^I set the (?:ProtoBuf|Protobuf|protobuf) at "([^"]*)" to (-?\d+)$/ do |field, val|
|
25
|
+
ProtobufSpec::Builder.protobuf.send("#{field}=".to_sym, val.to_i)
|
26
|
+
end
|
27
|
+
|
28
|
+
Given /^I set the (?:ProtoBuf|Protobuf|protobuf) at "([^"]*)" to (-?\d+\.\d+)$/ do |field, val|
|
29
|
+
ProtobufSpec::Builder.protobuf.send("#{field}=".to_sym, val.to_f)
|
30
|
+
end
|
31
|
+
|
32
|
+
Given /^I create the following (?:ProtoBuf|Protobuf|protobuf) of type "([^"]*)":$/ do |proto_type, proto_as_json|
|
33
|
+
steps %{Given I create a ProtoBuf of type "#{proto_type}"}
|
34
|
+
|
35
|
+
json = JSON.parse proto_as_json
|
36
|
+
ProtobufSpec::Builder.protobuf.fields.each_value do |field|
|
37
|
+
field_name = field.name.to_s
|
38
|
+
ProtobufSpec::Builder.protobuf[field_name] = json[field_name] if json.has_key? field_name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
When /^I deserialize a (?:ProtoBuf|Protobuf|protobuf) of type "([^"]*)" from "([^"]*)"$/ do |proto_type, serial|
|
43
|
+
steps %{Given I create a ProtoBuf of type "#{proto_type}"}
|
44
|
+
ProtobufSpec::Builder.protobuf.parse_from_string CukeMem.remember(serial)
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path("../../protobuf_spec", __FILE__)
|
2
|
+
require 'cuke_mem'
|
3
|
+
|
4
|
+
World(JsonSpec::Helpers, JsonSpec::Matchers)
|
5
|
+
World(ProtobufSpec::Matchers)
|
6
|
+
|
7
|
+
When /^(?:I )?keep the (?:ProtoBuf|protobuf|Protobuf)(?: response)?(?: at "(.*)")? as "(.*)"$/ do |path, key|
|
8
|
+
CukeMem.memorize(key, normalize_json(last_protobuf.to_json, path))
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)?(?: at "(.*)")? should( not)? include:$/ do |path, negative, json|
|
12
|
+
if negative
|
13
|
+
last_protobuf.to_json.should_not include_json(CukeMem.remember(json)).at_path(path)
|
14
|
+
else
|
15
|
+
last_protobuf.to_json.should include_json(CukeMem.remember(json)).at_path(path)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)?(?: at "(.*)")? should( not)? include (".*"|\-?\d+(?:\.\d+)?(?:[eE][\+\-]?\d+)?|\[.*\]|%?\{.*\}|true|false|null)$/ do |path, negative, value|
|
20
|
+
if negative
|
21
|
+
last_protobuf.to_json.should_not include_json(CukeMem.remember(value)).at_path(path)
|
22
|
+
else
|
23
|
+
last_protobuf.to_json.should include_json(CukeMem.remember(value)).at_path(path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)?(?: at "(.*)")? should( not)? be:$/ do |path, negative, json|
|
28
|
+
if negative
|
29
|
+
last_protobuf.should_not be_protobuf_eql(CukeMem.remember(json)).at_path(path)
|
30
|
+
else
|
31
|
+
last_protobuf.should be_protobuf_eql(CukeMem.remember(json)).at_path(path)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)?(?: at "(.*)")? should( not)? be (".*"|\-?\d+(?:\.\d+)?(?:[eE][\+\-]?\d+)?|\[.*\]|%?\{.*\}|true|false|null)$/ do |path, negative, value|
|
36
|
+
if negative
|
37
|
+
last_protobuf.should_not be_protobuf_eql(CukeMem.remember(value)).at_path(path)
|
38
|
+
else
|
39
|
+
last_protobuf.should be_protobuf_eql(CukeMem.remember(value)).at_path(path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)?(?: at "(.*)")? should have the following:$/ do |base, table|
|
44
|
+
table.rows.each do |path, value|
|
45
|
+
path = [base, path].compact.join("/")
|
46
|
+
|
47
|
+
if value
|
48
|
+
step %(the protobuf at "#{path}" should be:), value
|
49
|
+
else
|
50
|
+
step %(the protobuf should have "#{path}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
Then /^the (?:ProtoBuf|Protobuf|protobuf)(?: response)? should( not)? have "(.*)"$/ do |negative, path|
|
58
|
+
if negative
|
59
|
+
last_protobuf.should_not have_protobuf_path(path)
|
60
|
+
else
|
61
|
+
last_protobuf.should have_protobuf_path(path)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
When /^I save the serialized (?:ProtoBuf|Protobuf|protobuf) as "([^"]*)"$/ do |key|
|
67
|
+
CukeMem.memorize key, last_protobuf.serialize_to_string
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'protobuf_spec/matchers/be_protobuf_eql'
|
2
|
+
require 'protobuf_spec/matchers/have_protobuf_path'
|
3
|
+
|
4
|
+
module ProtobufSpec
|
5
|
+
module Matchers
|
6
|
+
def be_protobuf_eql(expected=nil)
|
7
|
+
ProtobufSpec::Matchers::BeProtobufEql.new(expected)
|
8
|
+
end
|
9
|
+
|
10
|
+
def have_protobuf_path(path)
|
11
|
+
ProtobufSpec::Matchers::HaveProtobufPath.new(path)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.include(ProtobufSpec::Matchers)
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'json_spec/messages'
|
2
|
+
|
3
|
+
module ProtobufSpec
|
4
|
+
module Matchers
|
5
|
+
class BeProtobufEql
|
6
|
+
include JsonSpec::Messages
|
7
|
+
|
8
|
+
attr_reader :actual
|
9
|
+
|
10
|
+
def initialize(expected_json = nil)
|
11
|
+
@json_matcher= JsonSpec::Matchers::BeJsonEql.new expected_json
|
12
|
+
end
|
13
|
+
|
14
|
+
def at_path(path)
|
15
|
+
@path=path
|
16
|
+
@json_matcher.at_path path
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def matches?(protobuf)
|
21
|
+
@json_matcher.matches? protobuf.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
def failure_message_for_should
|
25
|
+
message_with_path("Expected equivalent Protobuf")
|
26
|
+
end
|
27
|
+
|
28
|
+
def negative_failure_message
|
29
|
+
message_with_path("Expected inequivalent Protobuf")
|
30
|
+
end
|
31
|
+
|
32
|
+
def description
|
33
|
+
message_with_path("equal Protobuf")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|