fix_spec 0.2.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/README.md +28 -1
- data/VERSION +1 -1
- data/features/builder.feature +164 -5
- data/features/equivalence_data_dictionary.feature +49 -1
- data/features/message_type.feature +11 -0
- data/features/nested_builder.feature +229 -2
- data/features/support/FIX50SP1.xml +9419 -0
- data/features/support/FIXT11.xml +383 -0
- data/features/support/env.rb +8 -0
- data/fix_spec.gemspec +10 -7
- data/lib/fix_spec/builder.rb +89 -27
- data/lib/fix_spec/configuration.rb +19 -2
- data/lib/fix_spec/cucumber.rb +1 -2
- data/spec/fix_spec/data_dictionary_spec.rb +12 -6
- metadata +32 -49
data/lib/fix_spec/builder.rb
CHANGED
@@ -9,21 +9,35 @@ module Builder
|
|
9
9
|
def self.message= msg
|
10
10
|
@message=msg
|
11
11
|
end
|
12
|
+
|
13
|
+
# Converts a FIX message string into a +quickfix.Message+.
|
14
|
+
#
|
15
|
+
# Params:
|
16
|
+
# +msg_string+:: the FIX message string
|
17
|
+
# +do_validation+:: if true, validation is performed using the DataDictionary
|
18
|
+
#
|
19
|
+
# Returns:
|
20
|
+
# +quickfix.Message+
|
21
|
+
#
|
22
|
+
# See also:
|
23
|
+
# +quickfix.MessageUtils#parse(Session, String)+
|
24
|
+
def self.parse_message msg_string, do_validation
|
25
|
+
begin_string = quickfix.MessageUtils.getStringField(msg_string, quickfix.field.BeginString::FIELD)
|
26
|
+
msg_type = quickfix.MessageUtils.getMessageType(msg_string)
|
27
|
+
payload_dict = quickfix.MessageUtils.isAdminMessage(msg_type) ? FIXSpec::session_data_dictionary : FIXSpec::application_data_dictionary
|
28
|
+
msg = quickfix.DefaultMessageFactory.new.create(begin_string, msg_type)
|
29
|
+
msg.parse(msg_string, FIXSpec::session_data_dictionary, payload_dict, do_validation)
|
30
|
+
msg
|
31
|
+
end
|
12
32
|
end
|
13
33
|
end
|
14
34
|
|
15
35
|
Given /^the following( unvalidated)? fix message:$/ do |unvalidated,fix_str|
|
16
|
-
|
17
|
-
unless unvalidated
|
18
|
-
FIXSpec::Builder.message = quickfix.MessageUtils.parse(factory, FIXSpec::data_dictionary, FIXSpec::Helpers.fixify_string(fix_str) )
|
19
|
-
else
|
20
|
-
FIXSpec::Builder.message = quickfix.MessageUtils.parse(factory, nil, FIXSpec::Helpers.fixify_string(fix_str) )
|
21
|
-
end
|
22
|
-
|
36
|
+
FIXSpec::Builder.message = FIXSpec::Builder.parse_message(FIXSpec::Helpers.fixify_string(fix_str), !unvalidated)
|
23
37
|
FIXSpec::Builder.message.should_not be_nil
|
24
38
|
end
|
25
39
|
|
26
|
-
Given /^I create a (?:fix|FIX|(
|
40
|
+
Given /^I create a (?:fix|FIX|(FIXT?\.\d+\.\d+)) message(?: of type "(.*)")?$/ do |begin_string, msg_type|
|
27
41
|
FIXSpec::Builder.message = quickfix.Message.new
|
28
42
|
|
29
43
|
unless begin_string.nil?
|
@@ -35,7 +49,7 @@ Given /^I create a (?:fix|FIX|(.*)) message(?: of type "(.*)")?$/ do |begin_stri
|
|
35
49
|
end
|
36
50
|
end
|
37
51
|
|
38
|
-
Given /^I create the following (?:fix|FIX|(
|
52
|
+
Given /^I create the following (?:fix|FIX|(FIXT?\.\d+\.\d+)) message(?: of type "(.*)")?:$/ do |begin_string, msg_type, table|
|
39
53
|
FIXSpec::Builder.message = quickfix.Message.new
|
40
54
|
|
41
55
|
unless begin_string.nil?
|
@@ -51,10 +65,64 @@ Given /^I create the following (?:fix|FIX|(.*)) message(?: of type "(.*)")?:$/ d
|
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
54
|
-
|
55
|
-
|
56
68
|
Given /^I set the (?:FIX|fix) message at(?: tag)? "(.*?)" to (".*"|\-?\d+(?:\.\d+)?(?:[eE][\+\-]?\d+)?|\[.*\]|%?\{.*\}|true|false|null)$/ do |fieldName, fieldValue|
|
57
69
|
FIXSpec::Builder.message.should_not be_nil
|
70
|
+
set_fields(FIXSpec::Builder.message, fieldName.split('/'), fieldValue)
|
71
|
+
end
|
72
|
+
|
73
|
+
Given(/^I add the following "(.*?)" group:$/) do |grpType, table|
|
74
|
+
FIXSpec::Builder.message.should_not be_nil
|
75
|
+
|
76
|
+
list_field_order = []
|
77
|
+
table.raw.each do |fieldName, fieldValue|
|
78
|
+
list_field_order.push(FIXSpec::data_dictionary.getFieldTag(fieldName))
|
79
|
+
end
|
80
|
+
|
81
|
+
group = quickfix.Group.new(FIXSpec::data_dictionary.getFieldTag(grpType), list_field_order.first, (list_field_order.to_java :int))
|
82
|
+
|
83
|
+
table.raw.each do |fieldName, fieldValue|
|
84
|
+
add_field(group, fieldName, fieldValue)
|
85
|
+
end
|
86
|
+
|
87
|
+
FIXSpec::Builder.message.addGroup(group)
|
88
|
+
end
|
89
|
+
|
90
|
+
def set_fields msgPart, fieldName, fieldValue
|
91
|
+
if fieldName.is_a? String
|
92
|
+
add_field msgPart, fieldName, fieldValue
|
93
|
+
elsif fieldName.is_a? Array
|
94
|
+
if fieldName.length > 1
|
95
|
+
add_array_field msgPart, fieldName, fieldValue
|
96
|
+
else
|
97
|
+
add_field msgPart, fieldName.first, fieldValue
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_array_field msgPart, fieldArray, fieldValue
|
103
|
+
if !FIXSpec::data_dictionary.nil?
|
104
|
+
fieldName = fieldArray.shift
|
105
|
+
tag = FIXSpec::data_dictionary.getFieldTag(fieldName)
|
106
|
+
fail "#{fieldName} is not a valid field" if tag == -1
|
107
|
+
|
108
|
+
arrayPosStr = fieldArray.shift
|
109
|
+
arrayPos = arrayPosStr.to_i
|
110
|
+
fail "#{arrayPos} is not a valid array index" unless arrayPos.to_s == arrayPosStr
|
111
|
+
fail "You need to specify a field for group #{fieldName}" if fieldArray.empty?
|
112
|
+
|
113
|
+
if msgPart.hasGroup(arrayPos+1, tag)
|
114
|
+
set_fields msgPart.getGroup(arrayPos+1, tag), fieldArray, fieldValue
|
115
|
+
else
|
116
|
+
group = quickfix.Group.new tag, -1
|
117
|
+
set_fields group, fieldArray, fieldValue
|
118
|
+
msgPart.addGroup group
|
119
|
+
end
|
120
|
+
else
|
121
|
+
fail "no data dictionary set"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def add_field msgPart, fieldName, fieldValue
|
58
126
|
|
59
127
|
#kill quotes
|
60
128
|
if fieldValue.match(/\"(.*)\"/)
|
@@ -64,34 +132,28 @@ Given /^I set the (?:FIX|fix) message at(?: tag)? "(.*?)" to (".*"|\-?\d+(?:\.\d
|
|
64
132
|
tag = -1
|
65
133
|
if !FIXSpec::data_dictionary.nil?
|
66
134
|
tag = FIXSpec::data_dictionary.getFieldTag(fieldName)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
msg = msg.get_header
|
72
|
-
elsif FIXSpec::data_dictionary.is_trailer_field(tag)
|
73
|
-
msg = msg.get_trailer
|
135
|
+
if FIXSpec::session_data_dictionary.is_header_field(tag)
|
136
|
+
msgPart = msgPart.get_header
|
137
|
+
elsif FIXSpec::session_data_dictionary.is_trailer_field(tag)
|
138
|
+
msgPart = msgPart.get_trailer
|
74
139
|
end
|
75
140
|
|
76
141
|
case FIXSpec::data_dictionary.get_field_type_enum(tag).get_name
|
77
142
|
when "INT","DAYOFMONTH" then
|
78
|
-
|
143
|
+
msgPart.setInt(tag, fieldValue.to_i)
|
79
144
|
when "PRICE","FLOAT","QTY" then
|
80
|
-
|
145
|
+
msgPart.setDouble(tag, fieldValue.to_f)
|
81
146
|
when "BOOLEAN" then
|
82
|
-
|
147
|
+
msgPart.setBoolean(tag, fieldValue == "true")
|
83
148
|
else
|
84
149
|
#enum description => enum value
|
85
150
|
#e.g. tag 54 "BUY"=>"1"
|
86
151
|
fieldValue = FIXSpec::data_dictionary.get_reverse_value_name(tag, fieldValue)
|
87
|
-
|
152
|
+
msgPart.setString(tag, fieldValue)
|
88
153
|
end
|
89
|
-
|
90
154
|
else
|
91
155
|
tag = fieldName.to_i
|
92
|
-
|
156
|
+
msgPart.setString(tag, fieldValue)
|
93
157
|
end
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
158
|
|
159
|
+
end
|
@@ -2,11 +2,28 @@ module FIXSpec
|
|
2
2
|
module Configuration
|
3
3
|
|
4
4
|
def data_dictionary=(dd)
|
5
|
-
|
5
|
+
self.application_data_dictionary=dd
|
6
|
+
self.session_data_dictionary=dd
|
6
7
|
end
|
7
8
|
|
8
9
|
def data_dictionary
|
9
|
-
|
10
|
+
self.application_data_dictionary
|
11
|
+
end
|
12
|
+
|
13
|
+
def application_data_dictionary=(dd)
|
14
|
+
@application_data_dictionary=dd
|
15
|
+
end
|
16
|
+
|
17
|
+
def application_data_dictionary
|
18
|
+
@application_data_dictionary
|
19
|
+
end
|
20
|
+
|
21
|
+
def session_data_dictionary=(dd)
|
22
|
+
@session_data_dictionary=dd
|
23
|
+
end
|
24
|
+
|
25
|
+
def session_data_dictionary
|
26
|
+
@session_data_dictionary
|
10
27
|
end
|
11
28
|
|
12
29
|
def reset
|
data/lib/fix_spec/cucumber.rb
CHANGED
@@ -30,8 +30,7 @@ Then /^the (?:fix|FIX)(?: message)?(?: at(?: tag)? "(.*?)")? should( not)? be:$/
|
|
30
30
|
# raw fix
|
31
31
|
if tag.nil? and not exp_value.match(/{*}/)
|
32
32
|
require 'fix_spec/builder'
|
33
|
-
|
34
|
-
exp_message = FIXSpec::Builder.message = quickfix.MessageUtils.parse(factory, nil, FIXSpec::Helpers.fixify_string(exp_value) )
|
33
|
+
exp_message = FIXSpec::Builder.parse_message(FIXSpec::Helpers.fixify_string(exp_value), false)
|
35
34
|
exp_value = FIXSpec::Helpers.message_to_unordered_json(exp_message)
|
36
35
|
end
|
37
36
|
|
@@ -1,27 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FIXSpec::DataDictionary do
|
4
|
-
let(:
|
4
|
+
let(:app_dict) {FIXSpec::DataDictionary.new "features/support/FIX50SP1.xml" }
|
5
|
+
let(:session_dict) {FIXSpec::DataDictionary.new "features/support/FIXT11.xml" }
|
5
6
|
|
6
7
|
it "is a quickfix.DataDictionary" do
|
7
|
-
|
8
|
+
app_dict.is_a?(quickfix.DataDictionary).should be_true
|
9
|
+
session_dict.is_a?(quickfix.DataDictionary).should be_true
|
8
10
|
end
|
9
11
|
|
10
12
|
describe "get_reverse_value_name" do
|
11
13
|
it "gives me back the same if not an enum or if we are giving an enum" do
|
12
|
-
|
14
|
+
app_dict.get_reverse_value_name(1, 'Ralph').should ==('Ralph')
|
15
|
+
session_dict.get_reverse_value_name(49, 'Hagbard').should ==('Hagbard')
|
13
16
|
end
|
14
17
|
|
15
18
|
it "gives me back the same if is an enum and no description matches" do
|
16
|
-
|
19
|
+
app_dict.get_reverse_value_name(39, 'D').should ==('D')
|
20
|
+
session_dict.get_reverse_value_name(141, 'X').should ==('X')
|
17
21
|
end
|
18
22
|
|
19
23
|
it "knows enum lookup" do
|
20
|
-
|
24
|
+
app_dict.get_reverse_value_name(54, 'BUY').should ==('1')
|
25
|
+
app_dict.get_reverse_value_name(35, 'NEWORDERSINGLE').should ==('D')
|
26
|
+
session_dict.get_reverse_value_name(35, 'ORDER_SINGLE').should ==('D')
|
21
27
|
end
|
22
28
|
|
23
29
|
it "knows how to map msg type" do
|
24
|
-
|
30
|
+
app_dict.get_reverse_value_name(35, 'NewOrderSingle').should ==('D')
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
metadata
CHANGED
@@ -1,128 +1,113 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fix_spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.2.1
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Chris Busbey
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name: json_spec
|
16
|
-
version_requirements: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ~>
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 1.1.1
|
21
|
-
none: false
|
22
14
|
requirement: !ruby/object:Gem::Requirement
|
23
15
|
requirements:
|
24
16
|
- - ~>
|
25
17
|
- !ruby/object:Gem::Version
|
26
18
|
version: 1.1.1
|
27
|
-
|
19
|
+
name: json_spec
|
28
20
|
prerelease: false
|
29
21
|
type: :runtime
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: quickfix-jruby
|
32
22
|
version_requirements: !ruby/object:Gem::Requirement
|
33
23
|
requirements:
|
34
24
|
- - ~>
|
35
25
|
- !ruby/object:Gem::Version
|
36
|
-
version: 1.
|
37
|
-
|
26
|
+
version: 1.1.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
38
28
|
requirement: !ruby/object:Gem::Requirement
|
39
29
|
requirements:
|
40
30
|
- - ~>
|
41
31
|
- !ruby/object:Gem::Version
|
42
|
-
version: 1.
|
43
|
-
|
32
|
+
version: 1.6.0
|
33
|
+
name: quickfix-jruby
|
44
34
|
prerelease: false
|
45
35
|
type: :runtime
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: cuke_mem
|
48
36
|
version_requirements: !ruby/object:Gem::Requirement
|
49
37
|
requirements:
|
50
38
|
- - ~>
|
51
39
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
53
|
-
|
40
|
+
version: 1.6.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
54
42
|
requirement: !ruby/object:Gem::Requirement
|
55
43
|
requirements:
|
56
44
|
- - ~>
|
57
45
|
- !ruby/object:Gem::Version
|
58
46
|
version: 0.1.1
|
59
|
-
|
47
|
+
name: cuke_mem
|
60
48
|
prerelease: false
|
61
49
|
type: :runtime
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: rspec
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - ~>
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
69
|
-
|
54
|
+
version: 0.1.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
70
56
|
requirement: !ruby/object:Gem::Requirement
|
71
57
|
requirements:
|
72
58
|
- - ~>
|
73
59
|
- !ruby/object:Gem::Version
|
74
60
|
version: '2.14'
|
75
|
-
|
61
|
+
name: rspec
|
76
62
|
prerelease: false
|
77
63
|
type: :development
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: jeweler
|
80
64
|
version_requirements: !ruby/object:Gem::Requirement
|
81
65
|
requirements:
|
82
66
|
- - ~>
|
83
67
|
- !ruby/object:Gem::Version
|
84
|
-
version: '
|
85
|
-
|
68
|
+
version: '2.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
86
70
|
requirement: !ruby/object:Gem::Requirement
|
87
71
|
requirements:
|
88
72
|
- - ~>
|
89
73
|
- !ruby/object:Gem::Version
|
90
74
|
version: '1.8'
|
91
|
-
|
75
|
+
name: jeweler
|
92
76
|
prerelease: false
|
93
77
|
type: :development
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: cucumber
|
96
78
|
version_requirements: !ruby/object:Gem::Requirement
|
97
79
|
requirements:
|
98
80
|
- - ~>
|
99
81
|
- !ruby/object:Gem::Version
|
100
|
-
version: '1.
|
101
|
-
|
82
|
+
version: '1.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
102
84
|
requirement: !ruby/object:Gem::Requirement
|
103
85
|
requirements:
|
104
86
|
- - ~>
|
105
87
|
- !ruby/object:Gem::Version
|
106
88
|
version: '1.3'
|
107
|
-
|
89
|
+
name: cucumber
|
108
90
|
prerelease: false
|
109
91
|
type: :development
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: rake
|
112
92
|
version_requirements: !ruby/object:Gem::Requirement
|
113
93
|
requirements:
|
114
94
|
- - ~>
|
115
95
|
- !ruby/object:Gem::Version
|
116
|
-
version: '
|
117
|
-
|
96
|
+
version: '1.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
118
98
|
requirement: !ruby/object:Gem::Requirement
|
119
99
|
requirements:
|
120
100
|
- - ~>
|
121
101
|
- !ruby/object:Gem::Version
|
122
102
|
version: '10.1'
|
123
|
-
|
103
|
+
name: rake
|
124
104
|
prerelease: false
|
125
105
|
type: :development
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.1'
|
126
111
|
description: Build and Inspect FIX Messages with RSpec and Cucumber steps
|
127
112
|
email: info@connamara.com
|
128
113
|
executables: []
|
@@ -151,6 +136,8 @@ files:
|
|
151
136
|
- features/paths.feature
|
152
137
|
- features/step_definitions/steps.rb
|
153
138
|
- features/support/FIX42.xml
|
139
|
+
- features/support/FIX50SP1.xml
|
140
|
+
- features/support/FIXT11.xml
|
154
141
|
- features/support/env.rb
|
155
142
|
- fix_spec.gemspec
|
156
143
|
- lib/fix_spec.rb
|
@@ -168,6 +155,7 @@ files:
|
|
168
155
|
homepage: http://github.com/connamara/fix_spec
|
169
156
|
licenses:
|
170
157
|
- GPL
|
158
|
+
metadata: {}
|
171
159
|
post_install_message:
|
172
160
|
rdoc_options: []
|
173
161
|
require_paths:
|
@@ -176,21 +164,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
164
|
requirements:
|
177
165
|
- - '>='
|
178
166
|
- !ruby/object:Gem::Version
|
179
|
-
segments:
|
180
|
-
- 0
|
181
|
-
hash: 2
|
182
167
|
version: '0'
|
183
|
-
none: false
|
184
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
169
|
requirements:
|
186
170
|
- - '>='
|
187
171
|
- !ruby/object:Gem::Version
|
188
172
|
version: '0'
|
189
|
-
none: false
|
190
173
|
requirements: []
|
191
174
|
rubyforge_project:
|
192
|
-
rubygems_version: 1.
|
175
|
+
rubygems_version: 2.1.9
|
193
176
|
signing_key:
|
194
|
-
specification_version:
|
177
|
+
specification_version: 4
|
195
178
|
summary: Build and Inspect FIX Messages
|
196
179
|
test_files: []
|