da_funk 0.7.8 → 0.7.9

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: c6f47faf4d2ca844d014c0d6555f6c539edab034
4
- data.tar.gz: e2c1f5a77ab22b9a84fad0b9bcfded1f78f63857
3
+ metadata.gz: b644f1f2ba4859e329c58c00d532b28f794bc6d3
4
+ data.tar.gz: 5e5a8cb854cac3ef9c3ffc85cc966f7806a20e92
5
5
  SHA512:
6
- metadata.gz: 7fb78e4c3d26198872111b6e824d09dd56be1c85841620bb64076d1e70e7dd5d7b4d055f431282f1cc04c3bb763fe8e2cfc0d28cbcb5971918493fa7d1ab9275
7
- data.tar.gz: d2bf38de9239f1a7031872a1a0423396997e64b777fa1159b2067b89161d256a5432e55295bdf5fc655786a0db69ea390eaf0f565a6abea5f2d15a4a4bd7a2d0
6
+ metadata.gz: abdfd8c783ba7fa829f9138cf1d11ad334b281d87106bac54f9998b79b32ddd800d24badfcf9443ddb0be9d077c69f52bff963452471c03ecc900b4264759a2a
7
+ data.tar.gz: 3d4d2c213a6975b8e250fb64064113ea96c8681591bd08391880d8ae4279d373803fb64dbafd9b878f4314031194d084de067db6a75e94a599c1b9547e90160c
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- da_funk (0.7.8)
4
+ da_funk (0.7.9)
5
5
  bundler (~> 1.7)
6
6
  cloudwalk_handshake (~> 0.6)
7
7
  funky-emv (~> 0.3)
@@ -12,11 +12,11 @@ GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
14
  cloudwalk_handshake (0.6.0)
15
- funky-emv (0.3.2)
15
+ funky-emv (0.4.0)
16
16
  funky-tlv (~> 0.2)
17
17
  funky-simplehttp (0.4.4)
18
18
  funky-tlv (0.2.2)
19
- posxml_parser (0.9.2)
19
+ posxml_parser (0.9.3)
20
20
  funky-emv (~> 0.3)
21
21
  rake (10.5.0)
22
22
  yard (0.9.5)
data/README.md CHANGED
@@ -1,140 +1,43 @@
1
- # DaFunk, a.k.a. CloudWalk Framework API
1
+ # DaFunk, happiness modularity
2
2
 
3
- Our goal at [CloudWalk][1] is to provide you with the
4
- necessary tools to build Point Of Sales (POS) applications
5
- in an easy and innovative way. To do so, we've developed
6
- a setup for MRuby programs that allows you to build and
7
- ship modern day applications to all of your terminals
8
- instantaneously. For that purpose, you will need to start
9
- using the API that is provided by this repository.
10
-
11
- ## Index
12
-
13
- - [Index](#index)
14
- - [What do I have here?](#what-do-i-have-here)
15
- - [How do I use this?](#how-do-i-use-this)
16
- - [Adding support to other platforms](#adding-support-to-other-platforms)
17
- - [I would like to contribute](#i-would-like-to-contribute)
3
+ DaFunk is a Embedded System Framework optimized for programmer happiness and sustainable productivity. It encourages modulatiry by adapter pattern an beautiful code by favoring convention over configuration.
18
4
 
19
5
  ## What do I have here?
20
6
 
21
7
  This repository contains a set of files and folder that compose the
22
- **CloudWalk Framework API**. The structure goes as follows:
8
+ **DaFunk API**. The structure goes as follows:
23
9
 
24
10
  - The `guides` directory, which contains a group of files that are intended to instruct how to use our framework.
25
11
  - An `imgs` directory, containing a picture that references the creative origins of this project.
26
12
  - A `lib` directory, which holds the main source code of our Framework API.
27
13
  - An `out`directory, which has a previous generated binary of this project. All builds target this directory.
28
14
  - A `test` directory with example test cases. Tests are divided by _integration_ tests and _unit_ tests.
29
- - A `utils` folder that contains some scripts which are useful for us to perform tests or interact with the command line environment.
30
-
31
- ## How do I use this?
32
15
 
33
- We strongly recommend using our framework API from our [application skeleton][3],
34
- it has all the minimal files and the structure needed to build your first application.
16
+ ## How do I use DaFunk?
35
17
 
36
- Essentially add to your `Gemfile`:
18
+ ### Embedded Projects
37
19
 
38
- ```ruby
39
- gem 'da_funk', :git => 'https://github.com/cloudwalkio/da_funk.git'
40
- ```
20
+ DaFunk is a gem to be used in MRuby environment, to provide the environment we created a CLI that is able to create, compile, run and test DaFunk Apps. You can check [here](http://github.com/da-funk/funky-cli)
41
21
 
42
- Then require `da_funk` in your application file!
22
+ Project creation flow in Ruby environment:
43
23
 
44
- ```ruby
45
- require 'da_funk'
46
24
  ```
47
-
48
- For more advanced users only wanting to use the `iso8583` module, here's how you require it:
49
-
50
- ```ruby
51
- require 'da_funk/iso8583'
25
+ funky-cli new project
26
+ cd project
27
+ bundle install
28
+ bundle exec rake test:unit
52
29
  ```
53
30
 
54
- A full tutorial on how to develop your first CloudWalk app
55
- can be found here: <https://docs.cloudwalk.io/en/cli>,
56
- or checkout this project's source code!
57
-
58
- ## Adding support to other platforms
59
-
60
- At CloudWalk we develop our framework targeting several POS terminal brands,
61
- physical devices and even virtual devices (such as our web emulator).
62
- To deal with the platform differences, we've created an abstraction layer
63
- in da_funk that helps us modify our framework's behavior for our targets,
64
- but ensuring the changes needed are minimal and separated from the
65
- framework's source code. As an example, we offer our project:
66
- [around_the_world][4], it is the recipe to have MRuby working on
67
- non embedded platforms and with full compliance with DaFunk API.
31
+ ### CRuby Projects
68
32
 
69
- The first step is to add `da_funk` as a submodule in your project, let's say you'll be hosting it on a git server,
70
- proceed with:
71
-
72
- git submodule add git@github.com:cloudwalkio/da_funk.git path/to/lib/da_funk
73
-
74
- Then, in your application, before starting anything, define your
75
- platform interface. The most important feature it needs to have is
76
- a `setup` method, which will be called to configure and initialize
77
- everything before the actual execution.
78
-
79
- ```ruby
80
- class PlatformInterface
81
- def self.setup
82
- # Configuration and initialization before apps execution
83
- end
84
- end
85
- ```
86
-
87
- Then you'll need to define your custom classes, but following the structure
88
- present in our [device][5] source code. These classes can be in the same file
89
- as the one that has the setup method, here is an example:
90
-
91
- ```ruby
92
- class PlatformInterface
93
- Network = ::Network # Implemented on C
94
- IO = ::IO # Implemeted on C
95
-
96
- class Display
97
- def self.clear
98
- ::IO.display_clear
99
- end
100
-
101
- def self.print_line(buf, row, column)
102
- # <class created on C or PlatformInterface>._print_line(buf, row, column)
103
- PlatformInterface._print_line(buf, row, column)
104
- end
105
- end
106
- end
107
- ```
108
-
109
- Some important notes regarding your platform interface:
110
-
111
- - Be careful with the instance object variable, leave that for DaFunk.
112
- - Put preference into using class methods instead of making calls as the interface.
113
- - We might revise this in the future, but for now: any method defined for
114
- platform-specific usages has to be defined with a name that starts with `_`,
115
- for example: `_myMethod`.
116
-
117
- Once you're comfortable with your platform class,
118
- we need to set it up as the adapter to use by altering DaFunk's device class:
33
+ For more advanced users only wanting to use the `iso8583` module, here's how you require it:
119
34
 
120
35
  ```ruby
121
- class Device # Class from DaFunk
122
- self.adapter = PlatformInterface
123
- end
36
+ require 'da_funk/iso8583'
124
37
  ```
125
38
 
126
- The adapter pattern is based is a well studied software design pattern,
127
- we recommend you to read the [Wiki article][7], it's an interesting bit
128
- of information that is rooted deep in our solutions.
129
-
130
- Finally build it with `rake` or in a more specific manner, with: `mrbc -o platform.mrb </path/to/mrblib/**/*/.rb>`
131
-
132
- In [this link][6] there is an example of the whole process. Enjoy the reading! :bowtie:
133
-
134
39
  ## I would like to contribute
135
40
 
136
- So, you want to propose changes to our skeleton??!! Thank you sir! We appreciate it :bowtie:
137
-
138
41
  Please follow the instructions:
139
42
 
140
43
  1. Fork it under your github account!
@@ -148,7 +51,7 @@ Please follow the instructions:
148
51
  ```
149
52
  The MIT License (MIT)
150
53
 
151
- Copyright (c) 2015 CloudWalk, Inc.
54
+ Copyright (c) 2016 CloudWalk, Inc.
152
55
 
153
56
  Permission is hereby granted, free of charge, to any person obtaining a copy
154
57
  of this software and associated documentation files (the "Software"), to deal
@@ -156,7 +59,7 @@ in the Software without restriction, including without limitation the rights
156
59
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
157
60
  copies of the Software, and to permit persons to whom the Software is
158
61
  furnished to do so, subject to the following conditions:
159
-
62
+ ###
160
63
  The above copyright notice and this permission notice shall be included in all
161
64
  copies or substantial portions of the Software.
162
65
 
@@ -169,12 +72,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
169
72
  SOFTWARE.
170
73
  ```
171
74
 
172
- [1]: https://www.cloudwalk.io
173
- [2]: https://www.cloudwalk.io/cli/
174
- [3]: https://github.com/cloudwalkio/cloudwalk-skeleton
175
- [4]: https://github.com/cloudwalkio/around_the_world
176
- [5]: https://github.com/cloudwalkio/da_funk/tree/master/lib/device
177
- [6]: https://github.com/cloudwalkio/mruby-cloudwalk-platform
178
- [7]: https://en.wikipedia.org/wiki/Adapter_pattern
179
-
180
75
  ![DaFunk](https://raw.githubusercontent.com/cloudwalkio/da_funk/master/imgs/daft-punk-da-funk.jpg)
@@ -1,5 +1,21 @@
1
1
  # DaFunk
2
2
 
3
+ ### 0.7.9 - 2016-10-03
4
+
5
+ - Implement seconds to Scheduler timer.
6
+ - Implement Device::IO.getxy to support touchscreen.
7
+ - Adopt try_user in Device::Network.
8
+ - Implement Helper#try_user to implement a user interruption.
9
+ - Use getc(milliseconds) instead of sleep to improve UX in Helper.
10
+ - Replace ContextLog.error by ContextLog.exception.
11
+ - Adopt DaFunk::Struct instead of Struct in Notifications.
12
+ - Send a Serf#event if creation interval exceed.
13
+ - Fix leak I18n copying translation in every call.
14
+ - Close serf socket if command has no reply.
15
+ - Implement DaFunk::Struct to avoid memory leaks from mruby.
16
+ - Check key cancel and return it at get_format.
17
+ - Update README.
18
+
3
19
  ### 0.7.8 - 2016-09-20
4
20
 
5
21
  - Fix windows system call in bin checks.
data/Rakefile CHANGED
@@ -29,6 +29,7 @@ FILES = FileList[
29
29
  "lib/da_funk/event_listener.rb",
30
30
  "lib/da_funk/event_handler.rb",
31
31
  "lib/da_funk/engine.rb",
32
+ "lib/da_funk/struct.rb",
32
33
  "lib/device.rb",
33
34
  "lib/device/audio.rb",
34
35
  "lib/device/crypto.rb",
@@ -21,8 +21,12 @@ module DaFunk
21
21
  end
22
22
 
23
23
  def schedule_timer
24
- if self.option.is_a?(Hash) && self.option.include?(:minutes)
25
- self.timer = Time.now + (self.option[:minutes].to_i * 60)
24
+ if self.option.is_a?(Hash)
25
+ if self.option.include?(:minutes)
26
+ self.timer = Time.now + (self.option[:minutes].to_i * 60)
27
+ elsif self.option.include?(:seconds)
28
+ self.timer = Time.now + self.option[:seconds]
29
+ end
26
30
  end
27
31
  end
28
32
 
@@ -23,7 +23,7 @@ module DaFunk
23
23
  I18n.pt(:attach_connected)
24
24
  else
25
25
  I18n.pt(:attach_fail, :args => [ret.to_s])
26
- sleep 4
26
+ getc(4000)
27
27
  return false
28
28
  end
29
29
  else
@@ -32,7 +32,7 @@ module DaFunk
32
32
  true
33
33
  else
34
34
  I18n.pt(:attach_device_not_configured)
35
- sleep(2)
35
+ getc(2000)
36
36
  false
37
37
  end
38
38
  end
@@ -88,6 +88,19 @@ module DaFunk
88
88
  key
89
89
  end
90
90
 
91
+ # must send nonblock proc
92
+ def try_user(timeout = Device::IO.timeout, &block)
93
+ time = timeout != 0 ? Time.now + timeout / 1000 : Time.now
94
+ processing = Hash.new(keep: true)
95
+ while(processing[:keep] && processing[:key] != Device::IO::CANCEL) do
96
+ if processing[:keep] = block.call(processing)
97
+ processing[:key] = getc(300)
98
+ end
99
+ break if time < Time.now
100
+ end
101
+ processing
102
+ end
103
+
91
104
  # Create a form menu.
92
105
  #
93
106
  # @param title [String] Text to display on line 0. If nil title won't be
@@ -62,7 +62,7 @@ class I18n
62
62
  end
63
63
 
64
64
  def self.get(symbol)
65
- language[symbol] || "No Translation"
65
+ (language[symbol] || "No Translation").dup
66
66
  end
67
67
 
68
68
  def self.pt(symbol, options = {})
@@ -0,0 +1,60 @@
1
+ module DaFunk
2
+ class Struct
3
+ attr_accessor :values, :members
4
+
5
+ def self.klass(*variables)
6
+ Proc.new do |*args|
7
+ struct = DaFunk::Struct.new(*variables)
8
+ args.each_with_index do |value, index|
9
+ struct.send("#{variables[index]}=", value)
10
+ end
11
+ struct
12
+ end
13
+ end
14
+
15
+ def initialize(*variables)
16
+ self.members = variables
17
+ self.values = variables.inject({}){|hash,v| hash[v.to_sym] = nil; hash}
18
+ end
19
+
20
+ def []=(key, value)
21
+ self.values[key] = value
22
+ end
23
+
24
+ def [](key)
25
+ self.values[key]
26
+ end
27
+
28
+ def method_missing(method, *args, &block)
29
+ param = method.to_s
30
+ p self.members
31
+ p param[0..-2]
32
+ if self.include? method
33
+ self[method]
34
+ elsif (param[-1..-1] == "=" && self.include?(key = param[0..-2]))
35
+ self[key.to_sym] = args.first
36
+ else
37
+ super
38
+ end
39
+ end
40
+
41
+ def include?(key)
42
+ self.members.include?(key.to_sym)
43
+ end
44
+
45
+ #def self.new(*variables)
46
+ #Class.new do
47
+ #define_method :initialize do |*args|
48
+ #members.each_with_index do |member, index|
49
+ #send("#{member}=", args[index])
50
+ #end
51
+ #end
52
+ #attr_accessor *variables
53
+ #define_method(:members) do
54
+ #variables
55
+ #end
56
+ #end
57
+ #end
58
+ end
59
+ end
60
+
@@ -1,4 +1,4 @@
1
1
  module DaFunk
2
- VERSION="0.7.8"
2
+ VERSION="0.7.9"
3
3
  end
4
4
 
@@ -138,6 +138,8 @@ class Device
138
138
  text = text[0..-2]
139
139
  elsif key == ENTER || key == KEY_TIMEOUT
140
140
  return text
141
+ elsif key == CANCEL
142
+ return CANCEL
141
143
  elsif key == F1 || key == DOWN || key == UP || key == ALPHA
142
144
  change_next(text, check_mask_type(text, options))
143
145
  next
@@ -207,6 +209,11 @@ class Device
207
209
  end
208
210
  end
209
211
 
212
+ # => {"return" => 1, "x" => 10, "y" => 50}
213
+ def self.getxy
214
+ super
215
+ end
216
+
210
217
  def self.insert_key?(key, options)
211
218
  if options[:mode] == IO_INPUT_MONEY || options[:mode] == IO_INPUT_DECIMAL || options[:mode] == IO_INPUT_NUMBERS
212
219
  NUMBERS.include?(key)
@@ -1,6 +1,7 @@
1
1
 
2
2
  class Device
3
3
  class Network
4
+ include DaFunk::Helper
4
5
 
5
6
  MEDIA_GPRS = "gprs"
6
7
  MEDIA_WIFI = "wifi"
@@ -24,10 +25,14 @@ class Device
24
25
  MODE_IBSS = "ibss"
25
26
  MODE_STATION = "station"
26
27
 
27
- TIMEOUT = -3320
28
- NO_CONNECTION = -1012
29
- SUCCESS = 0
30
- PROCESSING = 1
28
+ ERR_USER_CANCEL = -1010
29
+ TIMEOUT = -3320
30
+ NO_CONNECTION = -1012
31
+ SUCCESS = 0
32
+ PROCESSING = 1
33
+
34
+ POWER_OFF = 0
35
+ POWER_ON = 1
31
36
 
32
37
  # Not Supported
33
38
  #AUTH_WPA_EAP = "wpa_eap"
@@ -123,13 +128,16 @@ class Device
123
128
  end
124
129
 
125
130
  def self.dhcp_client(timeout)
126
- time = Time.now + (timeout.to_f / 1000.0)
127
131
  ret = adapter.dhcp_client_start
128
132
  if (ret == SUCCESS)
129
- ret = PROCESSING
130
- while(ret == PROCESSING) # 1 - In process to attach
131
- ret = adapter.dhcp_client_check
132
- break ret = TIMEOUT unless (time >= Time.now)
133
+ hash = try_user(timeout) do |processing|
134
+ processing[:ret] = adapter.dhcp_client_check
135
+ processing[:ret] == PROCESSING
136
+ end
137
+ ret = hash[:ret]
138
+
139
+ unless ret == SUCCESS
140
+ ret = ERR_USER_CANCEL if hash[:key] == Device::IO::CANCEL
133
141
  end
134
142
  end
135
143
  ret
@@ -141,14 +149,20 @@ class Device
141
149
  ret = Device::Network.init(*self.config)
142
150
  ret = Device::Network.connect
143
151
  ret = Device::Network.connected? if ret != SUCCESS
144
- while(ret == PROCESSING)
145
- ret = Device::Network.connected?
152
+
153
+ hash = try_user do |process|
154
+ process[:ret] = Device::Network.connected?
155
+ process[:ret] == PROCESSING # if true keep trying
146
156
  end
157
+ ret = hash[:ret]
158
+
147
159
  if ret == SUCCESS
148
- Device::Network.dhcp_client(20000) if (wifi? || ethernet?)
160
+ ret = Device::Network.dhcp_client(20000) if (wifi? || ethernet?)
149
161
  Device::Setting.network_configured = 1
150
162
  else
163
+ ret = ERR_USER_CANCEL if hash[:key] == Device::IO::CANCEL
151
164
  Device::Setting.network_configured = 0
165
+ Device::Network.disconnect
152
166
  end
153
167
  end
154
168
  ret
@@ -7,7 +7,7 @@ class Device
7
7
  DEFAULT_CREATION_INTERVAL = 3600
8
8
 
9
9
  class << self
10
- attr_accessor :callbacks, :current, :last_creation, :creation_interval
10
+ attr_accessor :callbacks, :current, :last_creation, :creation_interval, :last_event
11
11
  end
12
12
 
13
13
  self.callbacks = Hash.new
@@ -49,7 +49,10 @@ class Device
49
49
  end
50
50
 
51
51
  def self.create_fiber?(force = false)
52
- (! Device::Setting.company_name.empty?) && (! Device::Setting.logical_number.empty?) && (force || self.valid_creation_interval?)
52
+ (! Device::Setting.company_name.empty?) &&
53
+ (! Device::Setting.logical_number.empty?) &&
54
+ (force || self.valid_creation_interval?) &&
55
+ Device::ParamsDat.file["notification_enabled"] == "1"
53
56
  end
54
57
 
55
58
  def self.valid_creation_interval?
@@ -107,14 +110,28 @@ class Device
107
110
  end
108
111
  end
109
112
 
113
+ def valid_event_interval?
114
+ if @last_event
115
+ (@last_event + Notification.creation_interval) < Time.now
116
+ else
117
+ true
118
+ end
119
+ end
120
+
110
121
  private
111
122
  def reply(conn, ev)
112
123
  if ev.is_a?(Hash)
113
124
  if ev["Event"] == "user" && ev["Payload"] && ev["Payload"].include?("Id")
114
125
  index = ev["Payload"].index("\"Id")
115
126
  id = ev["Payload"][(index+7)..(index+38)]
127
+ @last_event = Time.now
116
128
  conn.event(event_name, "{\"Id\"=>\"#{id}\"}", false)
117
129
  end
130
+ elsif ev.nil?
131
+ if self.valid_event_interval?
132
+ @last_event = Time.now
133
+ conn.event(event_name, "", false)
134
+ end
118
135
  end
119
136
  end
120
137
 
@@ -132,6 +149,7 @@ class Device
132
149
  Fiber.new do
133
150
  begin
134
151
  Serfx.connect(socket_block: Device::Network.socket, timeout: timeout, stream_timeout: stream_timeout) do |conn|
152
+ @last_event = Time.now
135
153
  conn.auth(CloudwalkTOTP.at)
136
154
  Device::Notification.last_creation = Time.now
137
155
  conn.stream(subscription) { |ev| reply(conn, ev) }
@@ -3,7 +3,7 @@ class Device
3
3
  attr_reader :on, :before, :after, :description
4
4
  attr_accessor :results
5
5
 
6
- CallbackResult = Struct.new(:before_execute, :result, :after_execute)
6
+ CallbackResult = DaFunk::Struct.klass(:before_execute, :result, :after_execute)
7
7
 
8
8
  def initialize(description, procs = {})
9
9
  @description = description
@@ -20,7 +20,7 @@ class Device
20
20
 
21
21
  def call(event, moment = :on)
22
22
  if support?(moment)
23
- results[moment] << CallbackResult.new(
23
+ results[moment] << CallbackResult.call(
24
24
  Time.now,
25
25
  perform(event, moment),
26
26
  Time.now
@@ -134,7 +134,7 @@ class Device
134
134
  rescue SocketError
135
135
  return COMMUNICATION_ERROR
136
136
  rescue => e
137
- ContextLog.error(e, e.backtrace)
137
+ ContextLog.exception(e, e.backtrace)
138
138
  return IO_ERROR
139
139
  end
140
140
 
@@ -177,7 +177,7 @@ module ISO8583
177
177
  dt.strftime(fmt)
178
178
  rescue => e
179
179
  msg = "Invalid format encoding: #{date}, must be #{fmt}."
180
- ContextLog.error(e, e.backtrace, msg)
180
+ ContextLog.exception(e, e.backtrace, msg)
181
181
  raise ISO8583Exception.new(msg)
182
182
  end
183
183
  else
@@ -190,7 +190,7 @@ module ISO8583
190
190
  DateTime.strptime(str, fmt)
191
191
  rescue => e
192
192
  msg = "Invalid format decoding: #{str}, must be #{fmt}."
193
- ContextLog.error(e, e.backtrace, msg)
193
+ ContextLog.exception(e, e.backtrace, msg)
194
194
  raise ISO8583Exception.new(msg)
195
195
  end
196
196
  }
@@ -39,7 +39,7 @@ module ISO8583
39
39
  begin
40
40
  real_value = codec.decode(raw_value)
41
41
  rescue => e
42
- ContextLog.error e, e.backtrace
42
+ ContextLog.exception e, e.backtrace
43
43
  raise ISO8583ParseException.new(e.message+" (#{name})")
44
44
  end
45
45
 
@@ -56,7 +56,7 @@ module ISO8583
56
56
  begin
57
57
  encoded_value = codec.encode(value)
58
58
  rescue ISO8583Exception => e
59
- ContextLog.error(e, e.backtrace, "#{e.message} (#{name})")
59
+ ContextLog.exception(e, e.backtrace, "#{e.message} (#{name})")
60
60
  raise ISO8583Exception.new(e.message+" (#{name})")
61
61
  end
62
62
 
@@ -118,9 +118,11 @@ module Serfx
118
118
  # raises [RPCError] exception if error string is not empty
119
119
  #
120
120
  # @param header [Hash] RPC response header as hash
121
- def check_rpc_error!(header)
121
+ def check_rpc_error!(header, must_return = false)
122
122
  if header
123
123
  raise RPCError, header['Error'] unless header['Error'].empty?
124
+ else
125
+ raise RPCError, "Socket Closed" if must_return
124
126
  end
125
127
  end
126
128
 
@@ -130,7 +132,7 @@ module Serfx
130
132
  # @return [Response]
131
133
  def read_response(command, read_timeout = self.timeout)
132
134
  header, body = read_data(read_timeout)
133
- check_rpc_error!(header)
135
+ check_rpc_error!(header, true)
134
136
  if COMMANDS[command].include?(:body)
135
137
  Response.new(header, body)
136
138
  else
@@ -12,7 +12,7 @@ module Serfx
12
12
  #
13
13
  # `{"Seq": 0, "Error": ""}`
14
14
  #
15
- Header = Struct.new(:seq, :error)
15
+ Header = DaFunk::Struct.klass(:seq, :error)
16
16
  attr_reader :header, :body
17
17
 
18
18
  # Constructs a response object from a given header and body.
@@ -20,7 +20,7 @@ module Serfx
20
20
  # @param header [Hash] header of the response as hash
21
21
  # @param body [Hash] body of the response as hash
22
22
  def initialize(header, body = nil)
23
- @header = Header.new(header['Seq'], header['Error']) if header
23
+ @header = Header.call(header['Seq'], header['Error']) if header
24
24
  @body = body
25
25
  end
26
26
  end
@@ -0,0 +1,20 @@
1
+
2
+ class DaFunkStructTest < DaFunk::Test.case
3
+ def setup
4
+ @klass = DaFunk::Struct.klass(:a, :b, :c)
5
+ @obj = @klass.call(10,20,30)
6
+ end
7
+
8
+ def test_struct
9
+ assert_equal 10, @obj.a
10
+ assert_equal 20, @obj.b
11
+ assert_equal 30, @obj.c
12
+ end
13
+
14
+ def test_struct_nil
15
+ @obj = @klass.call
16
+ assert_nil @obj.a
17
+ assert_nil @obj.a
18
+ assert_nil @obj.b
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: da_funk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thiago Scalone
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-20 00:00:00.000000000 Z
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -151,6 +151,7 @@ files:
151
151
  - lib/da_funk/rake_task.rb
152
152
  - lib/da_funk/screen.rb
153
153
  - lib/da_funk/screen_flow.rb
154
+ - lib/da_funk/struct.rb
154
155
  - lib/da_funk/test.rb
155
156
  - lib/da_funk/version.rb
156
157
  - lib/device.rb
@@ -205,6 +206,7 @@ files:
205
206
  - test/resources/shared/bitmap_gp.dat
206
207
  - test/test_helper.rb
207
208
  - test/unit/da_funk/event_listener_test.rb
209
+ - test/unit/da_funk/struct_test.rb
208
210
  - test/unit/device/application_test.rb
209
211
  - test/unit/device/display_test.rb
210
212
  - test/unit/device/helper_test.rb
@@ -252,6 +254,7 @@ test_files:
252
254
  - test/resources/shared/bitmap_gp.dat
253
255
  - test/test_helper.rb
254
256
  - test/unit/da_funk/event_listener_test.rb
257
+ - test/unit/da_funk/struct_test.rb
255
258
  - test/unit/device/application_test.rb
256
259
  - test/unit/device/display_test.rb
257
260
  - test/unit/device/helper_test.rb