dfhmdf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b63e9ac034b94142ef123c5557fe73b860e0f853
4
+ data.tar.gz: 749a0b27b492e45c7c83fb9c3588160a6e150b9b
5
+ SHA512:
6
+ metadata.gz: 9378f25ada91fd1bc9462d9189133c51c13bbc43d33f32b41cc4a241818b730c36fe41545180109c9d5faa4e658585555313f8c3119951bc461004c2c92ca51c
7
+ data.tar.gz: aea1f18ac9970760998a21538bfc7622a03110545dbe05cf7351357aae8b88a4753e3104eacca9788da43802125140e656f586f0cde7642959a61c51868602bc
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.lock
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'rspec'
5
+
6
+ gemspec
data/Gemspec ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Dave Nicolette
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # dfhmdf
2
+
3
+ Converts DFHMDF macro specifications into ```text_field``` definitions for use with the (https://github.com/cheezy/te3270/)[TE3270 gem]. The purpose is to eliminate the need for you to count the characters across and down a 3270 screen to determine the X and Y coordinates and the length of each field you wish to define for TE3270.
4
+
5
+ ## Example
6
+
7
+ Given a BMS macro source file named ```myscreen.txt``` with the following contents:
8
+
9
+ ```
10
+ QCKSET DFHMSD TYPE=MAP,STORAGE=AUTO,MODE=OUT,LANG=COBOL,TIOAPFX=YES
11
+ QCKMAP DFHMDI SIZE=(24,80),LINE=1,COLUMN=1,CTRL=ALARM
12
+ DFHMDF POS=(1,1),LENGTH=3,ATTRB=(ASKIP,BRT),INITIAL='QCK'
13
+ DFHMDF POS=(1,26),LENGTH=28,ATTRB=(ASKIP,NORM), X
14
+ INITIAL='Quick Customer Account Check'
15
+ DFHMDF POS=(3,1),LENGTH=8,ATTRB=(ASKIP,NORM),INITIAL='Account:'
16
+ ACCTNO DFHMDF POS=(3,13),LENGTH=7,ATTRB=(ASKIP,NORM)
17
+ DFHMDF POS=(4,1),LENGTH=5,ATTRB=(ASKIP,NORM),INITIAL='Name:'
18
+ SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM)
19
+ FNAME DFHMDF POS=(4,30),LENGTH=10,ATTRB=(ASKIP,NORM)
20
+ DFHMDF POS=(5,1),LENGTH=11,ATTRB=(ASKIP,NORM),INITIAL='Max charge:'
21
+ CHG DFHMDF POS=(5,13),ATTRB=(ASKIP,NORM),PICOUT='$,$$0.00'
22
+ MSG DFHMDF LENGTH=20,POS=(7,1),ATTRB=(ASKIP,NORM)
23
+ DFHMSD TYPE=FINAL
24
+ ```
25
+
26
+ run ```dfhmdf`` as a command-line utility:
27
+
28
+ ```sh
29
+ dfhmdf macro-source > target-file
30
+ ```
31
+
32
+ to produce the following output:
33
+
34
+ ```ruby
35
+ text_field(:acctno, 4, 13, 7)
36
+ text_field(:surname, 5, 13, 15)
37
+ text_field(:fname, 5, 30, 10)
38
+ text_field(:chg, 6, 13, 8)
39
+ text_field(:msg, 8, 1, 20)
40
+ ```
41
+
42
+ From the example you may surmise:
43
+
44
+ 1. It only pays attention to DFHMDF macros.
45
+ 1. It uses the downcased label value as the TE3270 field name, or a name like 'x14y12' for unlabeled DFHMDF macros.
46
+ 1. It adjusts the X axis offset to account for the attribute byte.
47
+ 1. When PICOUT is specified instead of LENGTH, it derives the length from the PICOUT value.
48
+ 1. It generates only ```text_field``` definitions, and not a complete TE3270 screen class.
49
+
50
+ So, if you have coded a TE3270 screen class like this:
51
+
52
+ ```ruby
53
+ class MainframeScreen
54
+ include TE3270
55
+
56
+ def login(username, password)
57
+ self.userid = username
58
+ self.password = password
59
+ end
60
+ end
61
+
62
+ emulator = TE3270.emulator_for :extra do |platform|
63
+ platform.session_file = 'sessionfile.edp'
64
+ end
65
+ my_screen = MainframeScreen.new(emulator)
66
+ my_screen.userid = 'the_id'
67
+ my_screen.password = 'the_password'
68
+ ```
69
+
70
+ then you can paste in the generated ```text_field``` definitions like this:
71
+
72
+ ```ruby
73
+ class MainframeScreen
74
+ include TE3270
75
+
76
+ text_field(:acctno, 4, 13, 7)
77
+ text_field(:surname, 5, 13, 15)
78
+ text_field(:fname, 5, 30, 10)
79
+ text_field(:chg, 6, 13, 8)
80
+ text_field(:msg, 8, 1, 20)
81
+
82
+ def login(username, password)
83
+ self.userid = username
84
+ self.password = password
85
+ end
86
+ end
87
+
88
+ emulator = TE3270.emulator_for :extra do |platform|
89
+ platform.session_file = 'sessionfile.edp'
90
+ end
91
+ my_screen = MainframeScreen.new(emulator)
92
+ my_screen.userid = 'the_id'
93
+ my_screen.password = 'the_password'
94
+ ```
95
+
96
+ ## Installation
97
+
98
+ Add this line to your application's Gemfile:
99
+
100
+ ```ruby
101
+ gem 'dfhmdf'
102
+ ```
103
+
104
+ And then execute:
105
+
106
+ $ bundle
107
+
108
+ or install it yourself as:
109
+
110
+ $ gem install dfhmdf
111
+
112
+ ## Contributing
113
+
114
+ 1. Fork it ( https://github.com/[my-github-username]/dfhmdf/fork )
115
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
116
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
117
+ 4. Push to the branch (`git push origin my-new-feature`)
118
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/dfhmdf ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/convert_dfhmdf'
4
+
5
+ convert = ConvertDfhmdf.new
6
+ convert.run
data/dfhmdf.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dfhmdf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dfhmdf"
8
+ spec.version = Dfhmdf::VERSION
9
+ spec.authors = ["Dave Nicolette"]
10
+ spec.email = ["davenicolette@gmail.com"]
11
+ spec.summary = %q{Interprets DFHMDF macros}
12
+ spec.description = %q{Generate text_field specifications for te3270 based on DFHMDF source}
13
+ spec.homepage = "http://github.com/neopragma/dfhmdf"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,66 @@
1
+ require_relative './dfhmdf'
2
+
3
+ class ConvertDfhmdf
4
+ include Dfhmdf
5
+
6
+ def run
7
+ open_file
8
+ begin
9
+ clear
10
+ ingest_macro
11
+ process_macro @macro_source
12
+ puts te3270_text_field if dfhmdf?
13
+ end while @eof == false
14
+ close_file
15
+ end
16
+
17
+ def process_macro dfhmdf_macro
18
+ parse_tokens tokenize_line dfhmdf_macro
19
+ end
20
+
21
+ def ingest_macro
22
+ macro_end = false
23
+ @macro_source = ''
24
+ current_line = read_line
25
+ begin
26
+ if current_line == nil || current_line.length < 72 || current_line[71] == ' '
27
+ macro_end = true
28
+ end
29
+ @macro_source << squish(current_line)
30
+ current_line = read_line unless macro_end
31
+ end while macro_end == false
32
+ @macro_source
33
+ end
34
+
35
+ def process_macro dfhmdf_macro
36
+ parse_tokens tokenize_line dfhmdf_macro
37
+ end
38
+
39
+ def squish str
40
+ str[71] = ' ' unless str.length < 72
41
+ str.split.join(' ')
42
+ end
43
+
44
+ def macro_source
45
+ @macro_source
46
+ end
47
+
48
+ def read_line
49
+ line = @source_file.readline
50
+ @eof = @source_file.eof?
51
+ line
52
+ end
53
+
54
+ def open_file
55
+ if ARGV[0] == nil
56
+ abort 'Usage: ruby make_fields.rb inputfilename'
57
+ end
58
+ @source_file = File.open(ARGV[0], 'r')
59
+ @eof = false
60
+ end
61
+
62
+ def close_file
63
+ @source_file.close
64
+ end
65
+
66
+ end
data/lib/dfhmdf.rb ADDED
@@ -0,0 +1,126 @@
1
+ module Dfhmdf
2
+
3
+ def te3270_text_field
4
+ "text_field(:#{field_label}, #{x_coordinate}, #{y_coordinate}, #{field_length})"
5
+ end
6
+
7
+ def clear
8
+ @field_label, @parameter_hash, @parameters, @tokens = nil
9
+ @dfhmdf = false
10
+ end
11
+
12
+ def tokenize_line input_line
13
+
14
+ # Want to split on spaces except when space occurs within single quotes.
15
+ # Should be able to do it with a regex. Unable to figure it out so far. Using brute force.
16
+ # This regex doesn't work but was as close as I was able to get.
17
+ # @tokens = [@tokens, input_line.scan(/'.*?'|".*?"|\S+/)].compact.reduce([], :|)
18
+
19
+ new_tokens = []
20
+ temp = input_line.split
21
+ for i in 0..temp.length-1 do
22
+ if temp[i] != nil
23
+ if temp[i].include? "'"
24
+ temp[i] << ' ' << temp[i+1] unless temp[i+1] == nil
25
+ temp[i + 1] = nil
26
+ if new_tokens[i] == nil
27
+ new_tokens[i] = temp[i]
28
+ else
29
+ new_tokens[i] << temp[i]
30
+ end
31
+ else
32
+ new_tokens << temp[i]
33
+ end
34
+ end
35
+ end
36
+ @tokens = [@tokens, new_tokens].compact.reduce([], :|)
37
+ end
38
+
39
+ def parse_tokens tokens
40
+ @dfhmdf = false
41
+ if tokens[0] == 'DFHMDF'
42
+ @dfhmdf = true
43
+ @field_label = nil
44
+ operands = tokens[1]
45
+ elsif tokens[1] == 'DFHMDF'
46
+ @dfhmdf = true
47
+ @field_label = tokens[0].downcase
48
+ operands = tokens[2]
49
+ end
50
+ if dfhmdf? && tokens != nil && operands != nil && operands.include?('=')
51
+ parse_operands operands
52
+ end
53
+ end
54
+
55
+
56
+ def parse_operands operands_as_string
57
+ #-----------------------------------------------------------------------------
58
+ # Parse the operands in a macro source statement:
59
+ #
60
+ # LABEL MACRO OPERAND,OPERAND,OPERAND COMMENT X
61
+ # xxxxxxxxxxxxxxxxxxxxxxx
62
+ #
63
+ # Example
64
+ # -------
65
+ # from this...
66
+ # FIELD1 DFHMDF POS=(6,18),LENGTH=14,ATTRB=(ASKIP,NORM),INITIAL='Hello there'
67
+ #
68
+ # to this...
69
+ # { :pos => [ "6", "18" ], :length => "14", :attrb => [ "ASKIP", "NORM" ],
70
+ # :initial => "Hello there" }
71
+ #-----------------------------------------------------------------------------
72
+ @operands_hash = {}
73
+
74
+ # Split on comma except when the comma appears within parentheses.
75
+ # Couldn't figure out how to make it ignore commas within single quotes,
76
+ # so it misses PICOUT='$,$$0.00' and similar. Using brute force to handle it.
77
+
78
+ item = operands_as_string.split(/,(?![^(]*\))/)
79
+ for i in 0..item.length-1
80
+ if item[i].match(/^PICOUT=/)
81
+ item[i] << ',' << item[i+1]
82
+ end
83
+
84
+ if item[i].include? '='
85
+ key_value_pair = item[i].split('=')
86
+
87
+ # handle operand values consisting of a comma-separated list within parentheses
88
+ if key_value_pair[1][0] == '('
89
+ key_value_pair[1].gsub!(/[\(\)]/, '')
90
+ key_value_pair[1] = key_value_pair[1].split(',')
91
+ end
92
+
93
+ # handle operand values in single quotes
94
+ if key_value_pair[1][0] == "'"
95
+ key_value_pair[1].gsub!(/'/, '')
96
+ end
97
+
98
+ @operands_hash[key_value_pair[0].downcase.to_sym] = key_value_pair[1]
99
+ end
100
+ end
101
+ @operands_hash
102
+ end
103
+
104
+ def x_coordinate
105
+ (@operands_hash != nil && @operands_hash[:pos] && @operands_hash[:pos][0].to_i + 1) || 0
106
+ end
107
+
108
+ def y_coordinate
109
+ (@operands_hash != nil && @operands_hash[:pos] && @operands_hash[:pos][1].to_i) || 0
110
+ end
111
+
112
+ def field_length
113
+ (@operands_hash != nil && @operands_hash[:length] && @operands_hash[:length].to_i) ||
114
+ (@operands_hash != nil && @operands_hash[:initial] && @operands_hash[:initial].length) ||
115
+ (@operands_hash != nil && @operands_hash[:picout] && @operands_hash[:picout].length) || 0
116
+ end
117
+
118
+ def field_label
119
+ (@field_label == nil && "x#{x_coordinate}y#{y_coordinate}") || @field_label
120
+ end
121
+
122
+ def dfhmdf?
123
+ @dfhmdf
124
+ end
125
+
126
+ end
@@ -0,0 +1,3 @@
1
+ module Dfhmdf
2
+ VERSION = "0.0.1"
3
+ end
data/sample-macros ADDED
@@ -0,0 +1,15 @@
1
+ QCKSET DFHMSD TYPE=MAP,STORAGE=AUTO,MODE=OUT,LANG=COBOL,TIOAPFX=YES
2
+ QCKMAP DFHMDI SIZE=(24,80),LINE=1,COLUMN=1,CTRL=ALARM
3
+ DFHMDF POS=(1,1),LENGTH=3,ATTRB=(ASKIP,BRT),INITIAL='QCK'
4
+ TITLE DFHMDF POS=(1,26),LENGTH=28,ATTRB=(ASKIP,NORM), X
5
+ INITIAL='Quick Customer Account Check'
6
+ HEAD DFHMDF POS=(3,1),LENGTH=8,ATTRB=(ASKIP,NORM),INITIAL='Account:'
7
+ ACCTNO DFHMDF POS=(3,13),LENGTH=7,ATTRB=(ASKIP,NORM)
8
+ DFHMDF POS=(4,1),LENGTH=5,ATTRB=(ASKIP,NORM),INITIAL='Name:'
9
+ SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM)
10
+ FNAME DFHMDF POS=(4,30),LENGTH=10,ATTRB=(ASKIP,NORM)
11
+ DFHMDF POS=(5,1),LENGTH=11,ATTRB=(ASKIP,NORM), X
12
+ INITIAL='Max charge:'
13
+ CHG DFHMDF POS=(5,13),ATTRB=(ASKIP,NORM),PICOUT='$,$$0.00'
14
+ MSG DFHMDF LENGTH=20,POS=(7,1),ATTRB=(ASKIP,NORM)
15
+ DFHMSD TYPE=FINAL
@@ -0,0 +1,49 @@
1
+ require 'convert_dfhmdf'
2
+
3
+ describe ConvertDfhmdf do
4
+
5
+ before(:each) do
6
+ @screen_def = ConvertDfhmdf.new
7
+ end
8
+
9
+ describe "#process_macro" do
10
+ it "handles a DFHMDF macro" do
11
+ @screen_def.process_macro 'SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM)'
12
+ expect(@screen_def.dfhmdf?).to be(true)
13
+ expect(@screen_def.field_label).to eq('surname')
14
+ expect(@screen_def.x_coordinate).to eq(5)
15
+ expect(@screen_def.y_coordinate).to eq(13)
16
+ expect(@screen_def.field_length).to eq(15)
17
+ end
18
+ it "ignores macros other than DFHMDF" do
19
+ @screen_def.process_macro 'QCKSET DFHMSD TYPE=MAP,STORAGE=AUTO,MODE=OUT,LANG=COBOL,TIOAPFX=YES'
20
+ expect(@screen_def.dfhmdf?).to be(false)
21
+ expect(@screen_def.field_label).to eq('x0y0')
22
+ expect(@screen_def.x_coordinate).to eq(0)
23
+ expect(@screen_def.y_coordinate).to eq(0)
24
+ expect(@screen_def.field_length).to eq(0)
25
+ end
26
+ end
27
+
28
+ describe "#ingest_macro" do
29
+ it "stores macro source coded on a single line" do
30
+ allow(@screen_def).to receive(:read_line).and_return('SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM)')
31
+ @screen_def.ingest_macro
32
+ expect(@screen_def.macro_source).to eq('SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM)')
33
+ end
34
+
35
+ it "stores macro source coded on multiple lines" do
36
+ allow(@screen_def).to receive(:read_line).and_return(
37
+ # 1 2 3 4 5 6 7 8
38
+ # 12345678901234567890123456789012345678901234567890123456789012345678901234567890
39
+ 'SURNAME DFHMDF POS=(4,13), X',
40
+ ' LENGTH=15, X',
41
+ ' ATTRB=(ASKIP,NORM), X',
42
+ ' INITIAL=\'Name here\'')
43
+ @screen_def.ingest_macro
44
+ expect(@screen_def.macro_source)
45
+ .to eq('SURNAME DFHMDF POS=(4,13),LENGTH=15,ATTRB=(ASKIP,NORM),INITIAL=\'Name here\'')
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,208 @@
1
+ require 'dfhmdf'
2
+
3
+ class ScreenDef
4
+ include Dfhmdf
5
+
6
+ def operands_hash value
7
+ @operands_hash = value
8
+ end
9
+
10
+ def field_label= value
11
+ @field_label = value
12
+ end
13
+
14
+ end
15
+
16
+ describe ScreenDef do
17
+
18
+ before(:each) do
19
+ @screen_def = ScreenDef.new
20
+ end
21
+
22
+ context "housekeeping" do
23
+ it "clears all temporary values relevant to processing a DFHMDF macro" do
24
+ @screen_def.clear
25
+ expect(@screen_def.dfhmdf?).to be(false)
26
+ expect(@screen_def.field_length).to eq(0)
27
+ expect(@screen_def.field_label).to eq('x0y0')
28
+ expect(@screen_def.x_coordinate).to eq(0)
29
+ expect(@screen_def.y_coordinate).to eq(0)
30
+ end
31
+ end
32
+
33
+ context "tokenizing" do
34
+ describe "#tokenize_line" do
35
+ it "collects tokens separated by spaces" do
36
+ expect(@screen_def.tokenize_line('abc de,fg,hijk lmnop'))
37
+ .to eq([ 'abc', 'de,fg,hijk', 'lmnop' ])
38
+ end
39
+
40
+ it "doesn't split on spaces that appear within quoted strings" do
41
+ expect(@screen_def.tokenize_line("abc de,'fg hi',jkl mnop"))
42
+ .to eq([ "abc", "de,'fg hi',jkl", "mnop" ])
43
+ end
44
+
45
+ it "splits properly when the last operand is a quoted string with a space" do
46
+ expect(@screen_def.tokenize_line("abc de,'fg hi',jkl"))
47
+ .to eq([ "abc", "de,'fg hi',jkl" ])
48
+ end
49
+ end
50
+ end
51
+
52
+ context "recognizing DFHMDF macros" do
53
+ describe "#parse_tokens" do
54
+ it "recognizes a DFHMDF macro with no label" do
55
+ @screen_def.parse_tokens([ 'DFHMDF', 'POS=(4,5),LENGTH=15', 'baz' ])
56
+ expect(@screen_def.dfhmdf?).to be(true)
57
+ end
58
+ end
59
+
60
+ describe "#parse_tokens" do
61
+ it "clears the previous value of field label when none is specified" do
62
+ @screen_def.field_label = 'aardvaark'
63
+ @screen_def.parse_tokens([ 'DFHMDF', 'foo', 'bar' ])
64
+ expect(@screen_def.field_label).to eql('x0y0')
65
+ end
66
+ end
67
+
68
+ describe "#parse_tokens" do
69
+ it "recognizes a DFHMDF macro with a label" do
70
+ @screen_def.parse_tokens([ 'FIELDNAME', 'DFHMDF', 'POS=(4,5),LENGTH=15', 'bar' ])
71
+ expect(@screen_def.dfhmdf?).to be(true)
72
+ end
73
+ end
74
+
75
+ describe "#parse_tokens" do
76
+ it "populates the field label when one is specified" do
77
+ @screen_def.parse_tokens([ 'FIELDNAME', 'DFHMDF', 'POS=(4,5),LENGTH=15', 'bar' ])
78
+ expect(@screen_def.field_label).to eq('fieldname')
79
+ end
80
+ end
81
+
82
+ describe "#parse_tokens" do
83
+ it "ignores source lines that do not contain a DFHMDF macro" do
84
+ @screen_def.parse_tokens [ 'foo', 'bar', 'DFHMDF', 'baz' ]
85
+ expect(@screen_def.dfhmdf?).to eq(false)
86
+ end
87
+ end
88
+ end
89
+
90
+ context "parsing macro operands" do
91
+ describe "#parse_operands" do
92
+ it "handles simple key-value pairs" do
93
+ expect(@screen_def.parse_operands("KEY1=15,KEY2=30"))
94
+ .to eq({ :key1 => "15", :key2 => "30" })
95
+ end
96
+
97
+ it "handles operands with quoted values" do
98
+ expect(@screen_def.parse_operands("KEY1='Quoted value 1',KEY2='Quoted value 2'"))
99
+ .to eq({ :key1 => "Quoted value 1", :key2 => "Quoted value 2" })
100
+ end
101
+
102
+ it "handles operands with comma-separated values in parentheses" do
103
+ expect(@screen_def.parse_operands("KEY1=(one,two),KEY2=(three,four)"))
104
+ .to eq({ :key1 => [ "one", "two" ], :key2 => [ "three", "four" ] })
105
+ end
106
+
107
+ it "handles a mix of operand formats" do
108
+ expect(@screen_def.parse_operands("POS=(6,18),LENGTH=14,ATTRB=(ASKIP,NORM),INITIAL='Hello there'"))
109
+ .to eq({ :pos => [ "6", "18" ], :length => "14", :attrb => [ "ASKIP", "NORM" ], :initial => "Hello there" })
110
+ end
111
+ end
112
+ end
113
+
114
+ context "determining field label" do
115
+ describe "#field_label" do
116
+ it "returns the field label that was specified on the DFHMDF macro" do
117
+ @screen_def.field_label = 'NAME'
118
+ expect(@screen_def.field_label).to eq('NAME')
119
+ end
120
+
121
+ it "derives a field label based on x and y coordinates when no label was specified" do
122
+ @screen_def.field_label = nil
123
+ @screen_def.operands_hash( { :pos => [ "5", "18" ] })
124
+ expect(@screen_def.field_label).to eq('x6y18')
125
+ end
126
+ end
127
+ end
128
+
129
+ context "determining field position" do
130
+ describe "#x_coordinate" do
131
+ it "returns 0 as the x coordinate if the position has not been determined" do
132
+ expect(@screen_def.x_coordinate).to eq(0)
133
+ end
134
+
135
+ it "returns 0 as the x coordinate if POS=(x,y) was not specified" do
136
+ @screen_def.operands_hash( { :foo => "bar" } )
137
+ expect(@screen_def.x_coordinate).to eq(0)
138
+ end
139
+
140
+ it "calculates the x coordinate value skipping the attribute byte" do
141
+ @screen_def.operands_hash( { :pos => ["5", "28"] } )
142
+ expect(@screen_def.x_coordinate).to eq(6)
143
+ end
144
+ end
145
+
146
+ describe "#y_coordinate" do
147
+ it "returns 0 as the y coordinate if the position has not been determined" do
148
+ expect(@screen_def.y_coordinate).to eq(0)
149
+ end
150
+
151
+ it "returns 0 as the y coordinate if POS=(x,y) was not specified" do
152
+ @screen_def.operands_hash( { :foo => "bar" } )
153
+ expect(@screen_def.y_coordinate).to eq(0)
154
+ end
155
+
156
+ it "returns the y coordinate value from the POS=(x,y) parameter" do
157
+ @screen_def.operands_hash( { :pos => ["5", "28"] } )
158
+ expect(@screen_def.y_coordinate).to eq(28)
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "determining field length" do
164
+ describe "handling the LENGTH= parameter of the DFHMDF macro" do
165
+ it "returns 0 as the length if the length has not been determined" do
166
+ expect(@screen_def.field_length).to eq(0)
167
+ end
168
+
169
+ it "returns 0 as the length if the length was not specified" do
170
+ @screen_def.operands_hash( { :foo => "bar" } )
171
+ expect(@screen_def.field_length).to eq(0)
172
+ end
173
+
174
+ it "returns the length value from the LENGTH= parameter" do
175
+ @screen_def.operands_hash( { :length => "34" })
176
+ expect(@screen_def.field_length).to eq(34)
177
+ end
178
+ end
179
+
180
+ describe "handling the PICOUT= parameter of the DFHMDF macro" do
181
+ it "derives the length based on the PICOUT value" do
182
+ @screen_def.operands_hash( { :picout => "$,$$0.00" })
183
+ expect(@screen_def.field_length).to eq(8)
184
+ end
185
+ end
186
+ end
187
+
188
+ describe "generating a text_field definition" do
189
+ it "generates a text_field definition for a field with a LENGTH= specification" do
190
+ @screen_def.field_label = 'myfield'
191
+ @screen_def.operands_hash({ :pos => [ "23", "6" ], :length => "14" })
192
+ expect(@screen_def.te3270_text_field).to eql('text_field(:myfield, 24, 6, 14)')
193
+ end
194
+
195
+ it "generates a text_field definition for a field with a PICOUT= specification" do
196
+ @screen_def.field_label = 'otherfld'
197
+ @screen_def.operands_hash({ :pos => [ "8", "16" ], :picout => "$$,$$0.00" })
198
+ expect(@screen_def.te3270_text_field).to eql('text_field(:otherfld, 9, 16, 9)')
199
+ end
200
+
201
+ it "generates a text_field definition for a field with INITIAL= and no LENGTH=" do
202
+ @screen_def.field_label = 'otherfld'
203
+ @screen_def.operands_hash({ :pos => [ "8", "16" ], :initial => "Hello" })
204
+ expect(@screen_def.te3270_text_field).to eql('text_field(:otherfld, 9, 16, 5)')
205
+ end
206
+ end
207
+
208
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'dfhmdf'
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dfhmdf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dave Nicolette
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Generate text_field specifications for te3270 based on DFHMDF source
42
+ email:
43
+ - davenicolette@gmail.com
44
+ executables:
45
+ - dfhmdf
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - Gemspec
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - bin/dfhmdf
56
+ - dfhmdf.gemspec
57
+ - lib/convert_dfhmdf.rb
58
+ - lib/dfhmdf.rb
59
+ - lib/dfhmdf/version.rb
60
+ - sample-macros
61
+ - spec/lib/dfhmdf/convert_dfhmdf_spec.rb
62
+ - spec/lib/dfhmdf/dfhmdf_spec.rb
63
+ - spec/spec_helper.rb
64
+ homepage: http://github.com/neopragma/dfhmdf
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.2.2
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Interprets DFHMDF macros
88
+ test_files:
89
+ - spec/lib/dfhmdf/convert_dfhmdf_spec.rb
90
+ - spec/lib/dfhmdf/dfhmdf_spec.rb
91
+ - spec/spec_helper.rb