butler-mainframe 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5b3e86c2581052e59a8f1e74ff1da11a09ebb3c
4
- data.tar.gz: ddb71edc9e79c6b0a487e975f9bf9b2074b80beb
3
+ metadata.gz: 5dd2c3f32dca8f7e61d0ed59e11d59a158f7ff21
4
+ data.tar.gz: bc1a34ae83ca18147105f6ada19bf936cc36a417
5
5
  SHA512:
6
- metadata.gz: 542c1c9854d0163f5562cbc1bf2216ddf5294599362c8a8dc27d8fa2aeb82798c6d12c0dac9b8d2aaec842f3c71628306432e64a45ef3df1b234eacf471a381c
7
- data.tar.gz: 2a176d220c4f589313277eb8674c255ce1fff43e0d61a004e8919f9b0406ea0885d0a9cc1e04c59dadfa77fa10c461de0805ad5ea11769c0d49355f2699cf17a
6
+ metadata.gz: c9dad70f5096a1bc38d53d8e5e9e3176e09ca29452d741e1c1f25158e3e471212227f4276d0d1016ab8f7e836476dadcd9d8b0528a986f05481debbf4b539067
7
+ data.tar.gz: dfeabba225bcbe7d395ce8cc0c7bf53f4a998c1cea8b4686489362a4b228f0e5ee796114d8850db079ceb8a2b53cc07edb94b268f8efe8a0ec5389614f893e32
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ 0.6.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.5.0...v0.6.0) October 29th, 2015
2
+ ------------------------------
3
+ * Improved rails integration
4
+ * Added rails model test with the scaffold generator, see documentation
5
+ * Added env parameter in the configuration file
6
+ * Several little improvements
7
+
1
8
  0.5.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.4.0...v0.5.0) October 26th, 2015
2
9
  ------------------------------
3
10
  * Moved sensible parameters in a separate yml file (private.yml) do not share it
data/README.md CHANGED
@@ -160,7 +160,7 @@ My advice is to use navigate method for generic navigation and use a specific mo
160
160
 
161
161
  ## With Rails
162
162
 
163
- This module can be use on rails project.
163
+ This gem can be use on rails project.
164
164
  Add in your gemfile
165
165
 
166
166
  gem 'butler-mainframe'
@@ -169,11 +169,11 @@ then
169
169
 
170
170
  bundle install
171
171
 
172
- run generator to copy configuration files suitable for the emulator you need
172
+ run generator to copy configuration files passing your emulator as parameter (default x3270)
173
173
 
174
- rails g butler:install --emulator=passport
174
+ rails g butler:install --emulator=pcomm
175
175
 
176
- You should have a model for every function to perform.
176
+ My advice is to have a model for every function.
177
177
  In this simple example i have to insert an invoice number on a cics map so i create the invoice model:
178
178
 
179
179
  rails generate scaffold invoice number:integer
@@ -222,12 +222,49 @@ Class Invoice
222
222
  end
223
223
  ```
224
224
 
225
- Massive uses or one shot depends on your needs.
226
- The uses are many and only limited by your imagination!
227
- Experiment and you'll find the solution right for you :rocket:
225
+ If massive uses or one shot depends on your needs and according to these must be optimized the function.
228
226
 
227
+ The uses are many and only limited by your imagination! :rocket:
229
228
 
230
- ## Test with rake
229
+ Experiment and you'll find the solution right for you
230
+
231
+ ## Test
232
+
233
+ ### Test models with rails
234
+
235
+ Add the butler test helper in yours rails config/application.rb before create the resource.
236
+ In this way will be added for you the test cases for that model.
237
+ Available only for the test unit framework.
238
+
239
+ ```ruby
240
+ config.generators do |g|
241
+ ...
242
+ g.test_framework :test_unit
243
+ g.helper :butler_mainframe_test
244
+ end
245
+ ```
246
+
247
+ For example if you created the invoice resource:
248
+
249
+ With rails 4:
250
+
251
+ rake test test\models\butler_mainframe_invoice_test.rb
252
+
253
+ Rails 3 is not tested yet:
254
+
255
+ ruby -I test unit butler_mainframe_invoice_test.rb
256
+
257
+ You should get something like this:
258
+
259
+ ** Connection established with PComm A **
260
+ ...
261
+ Session closed because started by this process with id 1234
262
+
263
+ Finished in 13.044988s, 0.1533 runs/s, 0.3066 assertions/s.
264
+
265
+ 2 runs, 4 assertions, 0 failures, 0 errors, 0 skips
266
+
267
+ ### Test with rake
231
268
 
232
269
  Simple embedded tests
233
270
 
@@ -8,7 +8,6 @@
8
8
 
9
9
  require 'core/configuration'
10
10
  require 'core/configuration_dynamic'
11
- require 'config/config'
12
11
 
13
12
  module ButlerMainframe
14
13
  def self.root
@@ -16,49 +15,28 @@ module ButlerMainframe
16
15
  end
17
16
  end
18
17
 
19
- # TODO
20
- # require 'i18n'
21
- # I18n.load_path=Dir['config/locales/*.yml']
22
- # I18n.locale = ButlerMainframe.configuration.language
18
+ # This project use monkey patch for 1.8 compatibility
19
+ require 'mainframe/host_base'
23
20
 
24
- env = Rails.env if defined?(Rails)
25
- env ||= $ARGV[0] if $ARGV
26
- env ||= "development"
27
- debug = env == "development" ? true : false
21
+ # puts "Butler Mainframe #{defined?(Rails) ? 'with' : 'without'} Rails" #DEBUG
22
+ if defined?(Rails)
23
+ # Rails use own configuration file into initializers folder
28
24
 
29
- # require the emulator sub class specified in the config.rb
30
- require "mainframe/emulators/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
31
-
32
-
33
- %w(settings.yml private.yml).each do |file|
34
- filepath = File.join(ButlerMainframe.root,'lib','config',file)
35
- ButlerMainframe::Settings.load!(filepath, :env => env) if File.exist? filepath
36
- end
37
-
38
- require 'mainframe/customization/active_record'
39
- # puts "Extending Host class with #{Host3270::ActiveRecord}" if debug
40
- # Use monkey patch for 1.8 compatibility
41
- class ButlerMainframe::Host
42
- include Host3270::ActiveRecord
43
- end
25
+ # This module adds additional methods useful only for projects rails
26
+ require 'mainframe/customization/active_record'
27
+ class ButlerMainframe::HostBase
28
+ include ButlerMainframe::ActiveRecord
29
+ end
30
+ else
31
+ # ...if it is not a rails project load configuration file
32
+ require 'config/config'
44
33
 
45
- require 'mainframe/customization/generic_functions'
46
- # puts "Extending Host class with #{Host3270::GenericFunctions}" if debug
47
- class ButlerMainframe::Host
48
- include Host3270::GenericFunctions
49
- end
34
+ # require the emulator sub class specified in the config.rb
35
+ raise "Define your host gateway in the configuration file!" unless ButlerMainframe.configuration.host_gateway
36
+ require "mainframe/emulators/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
50
37
 
51
- if defined?(Host3270::CustomFunctions)
52
- # puts "Extending Host class with #{Host3270::CustomFunctions}" if debug
53
- class ButlerMainframe::Host
54
- include Host3270::CustomFunctions
38
+ %w(settings.yml private.yml).each do |file|
39
+ filepath = File.join(ButlerMainframe.root,'lib','config',file)
40
+ ButlerMainframe::Settings.load!(filepath, :env => ButlerMainframe.configuration.env) if File.exist? filepath
55
41
  end
56
- end
57
-
58
- =begin
59
- # To test in irb
60
- require 'butler-mainframe'
61
- host=ButlerMainframe::Host.new(debug: :full)
62
- host.scan_page
63
- host.navigate :next
64
- =end
42
+ end
data/lib/config/config.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  ButlerMainframe.configure do |config|
2
- config.host_gateway = :x3270
3
- config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
4
- config.timeout = 6 # In seconds
2
+ # config.host_gateway = :x3270
3
+ # config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
4
+ # config.timeout = 6 # In seconds
5
5
  end
6
6
 
@@ -4,5 +4,6 @@ ButlerMainframe.configure do |config|
4
4
  config.session_url = 'https://YOUR_HOST_IP/zephyr/Ecomes.zwh?sessionprofile=3270dsp/Sessions/host3270'
5
5
  config.session_tag = 1
6
6
  config.timeout = 6000
7
+ #config.env = 'production'
7
8
  end
8
9
 
@@ -7,5 +7,6 @@ ButlerMainframe.configure do |config|
7
7
  config.session_path = '"C:/Program Files (x86)/IBM/Personal Communications/pcsws.exe" "C:/Users/YOUR_USER/AppData/Roaming/IBM/Personal Communications/host3270.ws" /Q /H /S=A'
8
8
  config.session_tag = 'A'
9
9
  config.timeout = 6000
10
+ #config.env = 'production'
10
11
  end
11
12
 
@@ -2,5 +2,6 @@ ButlerMainframe.configure do |config|
2
2
  config.host_gateway = :x3270
3
3
  config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
4
4
  config.timeout = 6 # In seconds
5
+ #config.env = 'production'
5
6
  end
6
7
 
@@ -2,7 +2,7 @@ module ButlerMainframe
2
2
  class Configuration
3
3
  attr_writer :allow_sign_up
4
4
 
5
- attr_accessor :language, :host_gateway, :browser_path, :session_url, :session_path, :session_tag, :timeout
5
+ attr_accessor :language, :host_gateway, :browser_path, :session_url, :session_path, :session_tag, :timeout, :env
6
6
 
7
7
  def initialize
8
8
  @language = :en
@@ -12,6 +12,7 @@ module ButlerMainframe
12
12
  @session_path = ""
13
13
  @session_tag = nil
14
14
  @timeout = 1000
15
+ @env = 'development'
15
16
  end
16
17
 
17
18
  end
@@ -12,12 +12,19 @@ module Butler
12
12
 
13
13
  def copy_to_local
14
14
  copy_file "butler/templates/custom_functions.rb", "config/initializers/butler_custom_functions.rb"
15
- copy_file "../config/settings.yml", "config/butler.yml"
15
+ copy_file "../config/settings.yml", "config/butler.yml"
16
+ copy_file "../config/private.yml", "config/butler_private.yml"
16
17
  file = "config/initializers/butler.rb"
17
18
  copy_file "../config/config_EXAMPLE_#{options[:emulator]}.rb", file
18
19
  append_file file do
19
20
  <<-FILE.gsub(/^ /, '')
20
- ButlerMainframe::Settings.load!(File.join(Rails.root,'config','butler.yml'), :env => Rails.env)
21
+ raise "Define your host gateway in the rails initializer file!" unless ButlerMainframe.configuration.host_gateway
22
+ require "mainframe/emulators/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
23
+
24
+ %w(butler.yml butler_private.yml).each do |file|
25
+ filepath = File.join(Rails.root,'config',file)
26
+ ButlerMainframe::Settings.load!(filepath, :env => Rails.env) if File.exist? filepath
27
+ end
21
28
  FILE
22
29
  end
23
30
  end
@@ -1,27 +1,16 @@
1
1
  # These modules contain extensions for the Host class
2
- module Host3270
2
+ module ButlerMainframe
3
3
  module CustomFunctions
4
4
  ### Insert here your custom methods ###
5
5
 
6
6
  ### Update default generic function ###
7
- # def do_enter; exec_command "ENTER" end
8
- #
9
- # def go_back; exec_command "PA2" end
10
- #
11
- # def do_confirm; exec_command "PF3" end
12
- #
13
- # def do_quit; exec_command "CLEAR" end
14
- #
15
- # def do_erase; exec_command "ERASE EOF" end
16
- #
17
- # # If you add your static screen you must add it in the navigation method to define how to manage it
7
+ # If you add your static screen you must add it in the navigation method to define how to manage it
18
8
  # def destination_list
19
- # [
20
- # :company_menu,
21
- # :cics_selection,
22
- # :session_login,
23
- # :next,
24
- # :back]
9
+ # [:company_menu,
10
+ # :cics_selection,
11
+ # :session_login,
12
+ # :next,
13
+ # :back]
25
14
  # end
26
15
  #
27
16
  # # Use navigation method to move through the static screens
@@ -32,91 +21,98 @@ module Host3270
32
21
  # # :raise_on_abend => false raise an exception if an abend is occured
33
22
  # def navigate destination, options={}
34
23
  # options = {
24
+ # :session_user => ButlerMainframe::Settings.session_user,
25
+ # :session_password => ButlerMainframe::Settings.session_password,
35
26
  # :cics => ButlerMainframe::Settings.cics,
36
- # :user => ButlerMainframe::Settings.user,
37
- # :password => ButlerMainframe::Settings.password,
27
+ # :company_menu => ButlerMainframe::Settings.company_menu,
38
28
  # :raise_on_abend => false
39
29
  # }.merge(options)
40
- # attempts_number = ButlerMainframe::Settings.navigation_iterations
30
+ # max_attempts_number = ButlerMainframe::Settings.max_attempts_number
41
31
  # transactions_cics = ButlerMainframe::Settings.transactions_cics
42
32
  #
43
33
  # raise "Destination #{destination} not valid, please use: #{destination_list.join(', ')}" unless destination_list.include? destination
44
- # bol_found = nil
45
- # attempts_number.times do
34
+ #
35
+ # puts "Navigating to #{destination}" if @debug
36
+ # destination_found = nil
37
+ # attempt_number = 0
38
+ # while !destination_found do
39
+ # attempt_number += 1
40
+ #
46
41
  # if abend?
42
+ # puts "Navigate: abend" if @debug
47
43
  # options[:raise_on_abend] ? raise(catch_abend) : do_quit
48
44
  # elsif company_menu?
45
+ # puts "Navigating to #{destination} from company menu" if @debug
49
46
  # case destination
50
47
  # when :cics_selection,
51
48
  # :session_login then
52
49
  # do_quit
53
50
  # when :back then
54
51
  # do_quit
55
- # bol_found = true; break
52
+ # destination_found = true
56
53
  # when :next then
57
- # company_menu
58
- # bol_found = true; break
59
- # when :company_menu then bol_found = true; break
54
+ # company_menu options[:company_menu]
55
+ # destination_found = true
56
+ # when :company_menu then destination_found = true
60
57
  # else
61
58
  # # Every other destination is forward
62
- # company_menu
59
+ # company_menu options[:company_menu]
63
60
  # end
64
61
  # elsif cics?
62
+ # puts "Navigating to #{destination} from cics" if @debug
65
63
  # case destination
66
64
  # when :cics_selection,
67
65
  # :session_login then
68
- # write ButlerMainframe::Settings.logoff_cics, :y => 1, :x => 1
69
- # do_enter
66
+ # execute_cics ButlerMainframe::Settings.logoff_cics
70
67
  # when :back then
71
- # write ButlerMainframe::Settings.logoff_cics, :y => 1, :x => 1
72
- # do_enter
73
- # bol_found = true; break
68
+ # execute_cics ButlerMainframe::Settings.logoff_cics
69
+ # destination_found = true
74
70
  # when :next then
75
- # write transactions_cics[:main_application], :y => 1, :x => 1
76
- # do_enter
77
- # bol_found = true; break
71
+ # execute_cics transactions_cics[:main_application]
72
+ # destination_found = true
78
73
  # when :company_menu then
79
- # write transactions_cics[:company_menu], :y => 1, :x => 1
80
- # do_enter
74
+ # execute_cics transactions_cics[:company_menu]
81
75
  # else
82
76
  # #If we are in CICS with blank screen start the first transaction
83
- # write transactions_cics[:main_application], :y => 1, :x => 1
84
- # do_enter
77
+ # execute_cics transactions_cics[:main_application]
85
78
  # end
86
79
  # elsif cics_selection?
80
+ # puts "Navigating to #{destination} from cics selection" if @debug
87
81
  # case destination
88
- # when :cics_selection then bol_found = true; break
82
+ # when :cics_selection then destination_found = true
89
83
  # when :session_login then exec_command("PF3")
90
84
  # when :next then
91
85
  # cics_selection options[:cics] if options[:cics]
92
- # bol_found = true; break
86
+ # destination_found = true
93
87
  # when :back then
94
88
  # exec_command("PF3")
95
- # bol_found = true; break
89
+ # destination_found = true
96
90
  # else
97
91
  # cics_selection options[:cics] if options[:cics]
98
92
  # end
99
93
  # elsif session_login?
94
+ # puts "Navigating to #{destination} from session login" if @debug
100
95
  # case destination
101
96
  # when :session_login,
102
- # :back then bol_found = true; break
97
+ # :back then destination_found = true
103
98
  # when :next then
104
- # session_login options[:user], options[:password] if options[:user] && options[:password]
105
- # bol_found = true; break
99
+ # session_login options[:session_user], options[:session_password]
100
+ # destination_found = true
106
101
  # else
107
- # session_login options[:user], options[:password] if options[:user] && options[:password]
102
+ # session_login options[:session_user], options[:session_password]
108
103
  # end
109
104
  # else
105
+ # puts "Navigating to #{destination} from unknown screen" if @debug
110
106
  # # If we do not know where we are...
111
107
  # case destination
112
- # when :session_login then
108
+ # when :session_login then
113
109
  # # ...to come back to the first screen we surely have to go back
114
110
  # go_back
115
111
  # when :back then
116
112
  # # ...we can try to go back (not all the screen may go back in the same way)
117
113
  # go_back
118
- # bol_found = true; break
119
- # when :next then
114
+ # destination_found = true
115
+ # when :next then
120
116
  # # ...but we dont know how to move forward
121
117
  # raise "Define how to go forward in the navigation method on generic function module"
122
118
  # else
@@ -124,10 +120,11 @@ module Host3270
124
120
  # raise "Destination #{destination} not defined in the current screen"
125
121
  # end
126
122
  # end
123
+ # break if attempt_number > max_attempts_number
127
124
  # wait_session
128
125
  # end
129
126
  #
130
- # raise "It was waiting #{destination} map instead of: #{screen_title(:rows => 2).strip}" unless bol_found
127
+ # raise "It was waiting #{destination} map instead of: #{screen_title(:rows => 2).strip}" unless destination_found
131
128
  # end
132
129
  #
133
130
  # # Check if we are the first blank cics screen
@@ -141,15 +138,20 @@ module Host3270
141
138
  # end
142
139
  #
143
140
  # # Login to mainframe
144
- # # param1 user
145
- # # param2 password [sensible data]
146
- # def session_login user, password
141
+ # # param1 user(array) [text, y, x]
142
+ # # param2 password(array) [text, y, x]
143
+ # def session_login ar_user, ar_password
147
144
  # puts "Starting session login..." if @debug
145
+ # user, y_user, x_user = ar_user
146
+ # raise "Check session user configuration! #{user} #{y_user} #{x_user}" unless user && y_user && x_user
147
+ # password, y_password, x_password = ar_password
148
+ # raise "Check session password configuration! #{password} #{y_password} #{x_password}" unless password && y_password && x_password
149
+ #
148
150
  # wait_session
149
151
  # #inizializza_sessione
150
152
  # raise "It was waiting session login map instead of: #{screen_title}" unless session_login?
151
- # write user, :y => 16, :x => 36
152
- # write password, :y => 17, :x => 36, :sensible_data => true
153
+ # write user, :y => y_user, :x => x_user
154
+ # write password, :y => y_password, :x => x_password, :sensible_data => true
153
155
  # do_enter
154
156
  # end
155
157
  #
@@ -159,12 +161,15 @@ module Host3270
159
161
  # end
160
162
  #
161
163
  # # On this map, we have to select the cics environment
162
- # # param1 cics usually is a number
163
- # def cics_selection cics
164
+ # # param1 cics(array) [text, y, x]
165
+ # def cics_selection ar_cics
164
166
  # puts "Starting selezione_cics..." if @debug
167
+ # cics, y_cics, x_cics = ar_cics
168
+ # raise "Check cics configuration! #{cics} #{y_cics} #{x_cics}" unless cics && y_cics && x_cics
169
+ #
165
170
  # wait_session
166
171
  # raise "It was waiting cics selezion map instead of: #{screen_title}, message: #{catch_message}" unless cics_selection?
167
- # write cics, :y => 23, :x => 14
172
+ # write cics, :y => y_cics, :x => x_cics
168
173
  # do_enter
169
174
  # wait_session 1
170
175
  # end
@@ -176,11 +181,14 @@ module Host3270
176
181
  #
177
182
  # # On this map, we have to select the cics environment
178
183
  # # param1 cics usually is a number
179
- # def company_menu
184
+ # def company_menu ar_menu
180
185
  # puts "Starting company menu..." if @debug
186
+ # menu, y_menu, x_menu = ar_menu
187
+ # raise "Check company menu configuration! #{menu} #{y_menu} #{x_menu}" unless menu && y_menu && x_menu
188
+ #
181
189
  # wait_session
182
190
  # raise "It was waiting company menu map instead of: #{screen_title}, message: #{catch_message}" unless company_menu?
183
- # write "01", :y => 24, :x => 43
191
+ # write menu, :y => y_menu, :x => x_menu
184
192
  # do_enter
185
193
  # end
186
194
  #
@@ -214,9 +222,24 @@ module Host3270
214
222
  # }.merge(options)
215
223
  # scan(:y1 => 1, :x1 => 1, :y2 => options[:rows], :x2 => 80)
216
224
  # end
225
+ #
226
+ # def execute_cics name
227
+ # write name, :y => 1, :x => 2
228
+ # do_enter
229
+ # end
230
+ #
231
+ # def do_enter; exec_command "ENTER" end
232
+ #
233
+ # def go_back; exec_command "PA2" end
234
+ #
235
+ # def do_confirm; exec_command "PF3" end
236
+ #
237
+ # def do_quit; exec_command "CLEAR" end
238
+ #
239
+ # def do_erase; exec_command "ERASE EOF" end
217
240
  end
218
241
  end
219
242
 
220
243
  class ButlerMainframe::Host
221
- include Host3270::CustomFunctions
244
+ include ButlerMainframe::CustomFunctions
222
245
  end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate butler_helper Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,5 @@
1
+ class Rails::ButlerMainframeTestGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ hook_for :test_framework
5
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate butler_helper Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,46 @@
1
+ require 'rails/generators/test_unit'
2
+ require 'rails/generators/resource_helpers'
3
+
4
+ module TestUnit # :nodoc:
5
+ module Generators # :nodoc:
6
+ class ButlerMainframeTestGenerator < Base # :nodoc:
7
+ include Rails::Generators::ResourceHelpers
8
+
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def create_test_file
12
+ create_file "test/#{/^4\./ === Rails.version ? 'models' : 'unit'}/butler_mainframe_#{file_name}_test.rb",
13
+ <<-FILE.gsub(/^ /, '')
14
+ require 'test_helper'
15
+
16
+ class #{class_name}Test < ActiveSupport::TestCase
17
+ test "Basic navigation" do
18
+ params = {:debug => true, :wait_debug => 0.5}
19
+ host = ButlerMainframe::Host.new(params)
20
+ host.navigate :session_login
21
+ assert host.session_login?, 'navigate :session_login => this is not the session login'
22
+
23
+ host.navigate :next
24
+ assert !host.session_login?, 'navigate :next => does not pass login screen'
25
+
26
+ host.close_session
27
+ assert host.action[:object] == nil, "Close session failed!"
28
+ end
29
+
30
+ test "#{class_name} navigation" do
31
+ params = {:debug => true, :wait_debug => 0.5}
32
+ host = ButlerMainframe::Host.new(params)
33
+
34
+ #host.navigate :your_starting_screen
35
+ # WRITE YOUR TEST
36
+
37
+ host.close_session
38
+ assert host.action[:object] == nil, "Close session failed!"
39
+ end
40
+ end
41
+ FILE
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,5 @@
1
1
  # These modules contain extensions for the Host class
2
- module Host3270
2
+ module ButlerMainframe
3
3
  # This module can be use on rails project.
4
4
  #
5
5
  # Create a polimorphic model:
@@ -1,25 +1,14 @@
1
1
  # These modules contain extensions for the Host class
2
- module Host3270
2
+ module ButlerMainframe
3
3
  module GenericFunctions
4
4
 
5
- def do_enter; exec_command "ENTER" end
6
-
7
- def go_back; exec_command "PA2" end
8
-
9
- def do_confirm; exec_command "PF3" end
10
-
11
- def do_quit; exec_command "CLEAR" end
12
-
13
- def do_erase; exec_command "ERASE EOF" end
14
-
15
5
  # If you add your static screen you must add it in the navigation method to define how to manage it
16
6
  def destination_list
17
- [
18
- :company_menu,
19
- :cics_selection,
20
- :session_login,
21
- :next,
22
- :back]
7
+ [:company_menu,
8
+ :cics_selection,
9
+ :session_login,
10
+ :next,
11
+ :back]
23
12
  end
24
13
 
25
14
  # Use navigation method to move through the static screens
@@ -236,6 +225,17 @@ module Host3270
236
225
  write name, :y => 1, :x => 2
237
226
  do_enter
238
227
  end
228
+
229
+ def do_enter; exec_command "ENTER" end
230
+
231
+ def go_back; exec_command "PA2" end
232
+
233
+ def do_confirm; exec_command "PF3" end
234
+
235
+ def do_quit; exec_command "CLEAR" end
236
+
237
+ def do_erase; exec_command "ERASE EOF" end
238
+
239
239
  end
240
240
 
241
241
  end
@@ -1,5 +1,4 @@
1
1
  require 'win32ole'
2
- require 'mainframe/host_base'
3
2
 
4
3
  # This class use Rocket 3270 emulator API
5
4
  # http://www.zephyrcorp.com/legacy-integration/Documentation/passport_host_integration_objects.htm
@@ -12,37 +11,37 @@ module ButlerMainframe
12
11
  def sub_create_object options={}
13
12
  str_obj = 'PASSPORT.System'
14
13
  puts "#{Time.now.strftime "%H:%M:%S"} Creating object #{str_obj}..." if @debug == :full
15
- @action[:ole] = WIN32OLE.new(str_obj)
16
- @screen = @action[:ole].Sessions(@session_tag).Screen if sub_object_created?
14
+ @action[:object] = WIN32OLE.new(str_obj)
15
+ @screen = @action[:object].Sessions(@session_tag).Screen if sub_object_created?
17
16
  end
18
17
 
19
18
  # Check is session is started
20
19
  def sub_object_created?
21
- res = @action[:ole] && @action[:ole].Sessions(@session_tag)
20
+ res = @action[:object] && @action[:object].Sessions(@session_tag)
22
21
  puts "#{Time.now.strftime "%H:%M:%S"} Terminal successfully detected" if @debug == :full && res
23
22
  res
24
23
  end
25
24
 
26
25
  # Check is session is operative
27
26
  def sub_object_ready?
28
- res = @action[:ole].Sessions(@session_tag).Connected == -1
27
+ res = @action[:object].Sessions(@session_tag).Connected == -1
29
28
  puts "#{Time.now.strftime "%H:%M:%S"} Session ready" if @debug == :full && res
30
29
  res
31
30
  end
32
31
 
33
32
  def sub_name
34
- "#{@action[:ole].Name} #{@action[:ole].Sessions(@session_tag).Name}"
33
+ "#{@action[:object].Name} #{@action[:object].Sessions(@session_tag).Name}"
35
34
  end
36
35
 
37
36
  def sub_fullname
38
- "#{sub_name} #{@action[:ole].Sessions(@session_tag).FullName}"
37
+ "#{sub_name} #{@action[:object].Sessions(@session_tag).FullName}"
39
38
  end
40
39
 
41
40
  #Ends the connection and closes the session
42
41
  def sub_close_session
43
- @action[:ole].Sessions(@session_tag).Close
44
- @action[:ole].Quit
45
- @action[:ole] = nil
42
+ @action[:object].Sessions(@session_tag).Close
43
+ @action[:object].Quit
44
+ @action[:object] = nil
46
45
  end
47
46
 
48
47
  #Execute keyboard command like PF1 or PA2 or ENTER ...
@@ -1,5 +1,4 @@
1
1
  require 'win32ole'
2
- require 'mainframe/host_base'
3
2
 
4
3
  # This class use IBM personal communication
5
4
  # http://www-01.ibm.com/support/knowledgecenter/SSEQ5Y_6.0.0/welcome.html
@@ -14,38 +13,38 @@ module ButlerMainframe
14
13
  def sub_create_object options={}
15
14
  str_obj = 'PComm.autECLSession'
16
15
  puts "#{Time.now.strftime "%H:%M:%S"} Creating object #{str_obj}..." if @debug == :full
17
- @action[:ole] = WIN32OLE.new(str_obj)
18
- @action[:ole].SetConnectionByName @session_tag
19
- @space = @action[:ole].autECLPS
20
- @screen = @action[:ole].autECLOIA
16
+ @action[:object] = WIN32OLE.new(str_obj)
17
+ @action[:object].SetConnectionByName @session_tag
18
+ @space = @action[:object].autECLPS
19
+ @screen = @action[:object].autECLOIA
21
20
  end
22
21
 
23
22
  # Check is session is started
24
23
  def sub_object_created?
25
- res = @action[:ole] && @action[:ole].CommStarted
24
+ res = @action[:object] && @action[:object].CommStarted
26
25
  puts "#{Time.now.strftime "%H:%M:%S"} Terminal successfully detected" if @debug == :full && res
27
26
  res
28
27
  end
29
28
 
30
29
  # Check is session is operative
31
30
  def sub_object_ready?
32
- res = @action[:ole].Ready
31
+ res = @action[:object].Ready
33
32
  puts "#{Time.now.strftime "%H:%M:%S"} Session ready" if @debug == :full && res
34
33
  res
35
34
  end
36
35
 
37
36
  def sub_name
38
- "PComm #{@action[:ole].Name}"
37
+ "PComm #{@action[:object].Name}"
39
38
  end
40
39
 
41
40
  def sub_fullname
42
- "#{sub_name} #{@action[:ole].ConnType}"
41
+ "#{sub_name} #{@action[:object].ConnType}"
43
42
  end
44
43
 
45
44
  #Ends the connection and closes the session
46
45
  def sub_close_session
47
- @action[:ole].StopCommunication
48
- @action[:ole] = nil
46
+ @action[:object].StopCommunication
47
+ @action[:object] = nil
49
48
  # See http://www-01.ibm.com/support/knowledgecenter/SSEQ5Y_6.0.0/com.ibm.pcomm.doc/books/html/admin_guide10.htm?lang=en
50
49
  Process.spawn "PCOMSTOP /S=#{@session_tag} /q" if @pid
51
50
  # Process.kill 9, @pid #Another way is to kill the process but the session start 2nd process pcscm.exe
@@ -1,5 +1,4 @@
1
1
  require 'open3'
2
- require 'mainframe/host_base'
3
2
 
4
3
  # This class use X3270, an interesting project open source
5
4
  # http://x3270.bgp.nu/Windows/wc3270-script.html
@@ -14,6 +13,7 @@ module ButlerMainframe
14
13
  puts "#{Time.now.strftime "%H:%M:%S"} Creating object #{str_obj}..." if @debug == :full
15
14
  @action = {}
16
15
  @action[:in], @action[:out], @action[:thr] = Open3.popen2e(str_obj)
16
+ @action[:object] = true
17
17
  sleep WAIT_AFTER_START_SESSION
18
18
  @pid = @action[:thr].pid
19
19
  end
@@ -44,6 +44,7 @@ module ButlerMainframe
44
44
  def sub_close_session
45
45
  @action[:in].close
46
46
  @action[:out].close
47
+ @action[:object] = nil
47
48
  end
48
49
 
49
50
  #Execute keyboard command like PF1 or PA2 or ENTER ...
@@ -1,7 +1,10 @@
1
+ require 'mainframe/customization/generic_functions'
2
+
1
3
  module ButlerMainframe
2
4
  # This is the host class base that contains high level logic
3
5
  # It uses sub method that have to be defined in the specific sub class
4
6
  class HostBase
7
+ include ButlerMainframe::GenericFunctions
5
8
 
6
9
  attr_reader :action, :wait
7
10
  attr_accessor :debug
@@ -40,6 +43,10 @@ module ButlerMainframe
40
43
 
41
44
  # Ends the connection and closes the session
42
45
  def close_session
46
+ # puts "[DEPRECATED] .close_session will no longer be available, please use .quit"
47
+ quit
48
+ end
49
+ def quit
43
50
  puts "Closing session with criterion \"#{@close_session}\"" if @debug
44
51
  case @close_session
45
52
  when :always
@@ -57,6 +64,7 @@ module ButlerMainframe
57
64
  end
58
65
  end
59
66
 
67
+
60
68
  # Sleep time between operations
61
69
  def wait_session wait=nil
62
70
  sleep(wait || (@debug ? @wait_debug : @wait))
data/test/test.rake CHANGED
@@ -43,27 +43,31 @@ def simple_iteration options={}
43
43
  host = options[:host] || ButlerMainframe::Host.new(params)
44
44
 
45
45
  navigate host, :session_login
46
-
47
46
  str_screen1 = host.scan_page
48
47
  raise 'host.scan_page' if str_screen1.empty?
48
+ raise 'navigate :session_login => this is not the session login' unless host.session_login?
49
49
 
50
50
  navigate host, :next
51
51
  str_screen2 = host.scan_page
52
- raise 'navigate :next does not pass login screen' if str_screen1 == str_screen2
52
+ raise 'navigate :next from :session_login => the screen is not changed' if str_screen1 == str_screen2
53
+
54
+ raise 'navigate :next => does not pass login screen' if host.session_login?
53
55
 
54
56
  navigate host, :next
55
- str_screen2 = host.scan_page
56
- raise 'navigate :next does not pass cics selection' if str_screen1 == str_screen2
57
+ raise 'navigate :next => does not pass cics selection' if host.cics_selection?
57
58
 
58
59
  # Go back until the first screen
59
60
  navigate host, :session_login
61
+ raise 'navigate :session_login => this is not the session login' unless host.session_login?
60
62
 
61
- raise "host.scan row failed" unless host.scan(:y => 1, :x => 1, :len => 80).size == 80
62
- raise "host.scan area failed" unless host.scan(:y1 => 1, :x1 => 1, :y2 => 3, :x2 => 80).size == 240
63
+ raise "host.scan row failed" unless host.scan(:y => 1, :x => 1, :len => ButlerMainframe::Host::MAX_TERMINAL_COLUMNS).size == ButlerMainframe::Host::MAX_TERMINAL_COLUMNS
64
+ raise "host.scan area failed" unless host.scan(:y1 => 1, :x1 => 1, :y2 => 3, :x2 => ButlerMainframe::Host::MAX_TERMINAL_COLUMNS).size == (ButlerMainframe::Host::MAX_TERMINAL_COLUMNS * 3)
63
65
 
64
66
  navigate host, :back
67
+ raise 'navigate :back from :session_login => this is not the session login' unless host.session_login?
65
68
 
66
69
  navigate host, :company_menu
70
+ raise 'navigate :company_menu from :session_login => this is not the company menu' unless host.company_menu?
67
71
 
68
72
  navigate host, :next
69
73
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: butler-mainframe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Mastrodonato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-26 00:00:00.000000000 Z
11
+ date: 2015-10-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This gem provides a virtual butler which can perform your custom tasks
14
14
  on a 3270 emulator. Choose your emulator, configure your task and discover a new
@@ -30,13 +30,16 @@ files:
30
30
  - lib/config/config_EXAMPLE_x3270.rb
31
31
  - lib/config/private.yml
32
32
  - lib/config/settings.yml
33
- - lib/config/settings_EXAMPLE.yml
34
33
  - lib/core/configuration.rb
35
34
  - lib/core/configuration_dynamic.rb
36
35
  - lib/generators/butler/USAGE
37
36
  - lib/generators/butler/install_generator.rb
38
37
  - lib/generators/butler/templates/custom_functions.rb
39
38
  - lib/generators/butler_mainframe.rb
39
+ - lib/generators/rails/butler_mainframe_test/USAGE
40
+ - lib/generators/rails/butler_mainframe_test/butler_mainframe_test_generator.rb
41
+ - lib/generators/test_unit/butler_mainframe_test/USAGE
42
+ - lib/generators/test_unit/butler_mainframe_test/butler_mainframe_test_generator.rb
40
43
  - lib/mainframe/customization/active_record.rb
41
44
  - lib/mainframe/customization/generic_functions.rb
42
45
  - lib/mainframe/emulators/passport.rb
@@ -1,25 +0,0 @@
1
- defaults: &defaults
2
- # The max number of iteration through static screen
3
- max_attempts_number: 20
4
- session_login_tag: 'EMSP00' # Use a regular expression
5
- cics_selection_tag: 'EMSP01' # Use a regular expression
6
- cics: ['7', 23, 14] # Text to write at coordinates y, x
7
- company_menu: ['01', 24, 43]
8
- logoff_cics: 'cesf logoff'
9
- company_menu_tag: '\*\* \*\* \*\* \*\*' # Use a regular expression
10
- # Starts these transactions from blank cics in order to move forward
11
- transactions_cics:
12
- company_menu: 'vita'
13
- main_application: 'life'
14
- #foo: add every variable you need and use it with => ButlerMainframe::Settings.foo
15
- # bar: sub variable are accessible with hash => ButlerMainframe::Settings.foo[:bar]
16
-
17
- development:
18
- <<: *defaults
19
-
20
- test:
21
- <<: *defaults
22
-
23
- production:
24
- <<: *defaults
25
- cics: ['4', 23, 14]