da_funk 0.4.4

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.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.yardopts +12 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.lock +21 -0
  6. data/README.md +108 -0
  7. data/README_GUIDE.md +52 -0
  8. data/RELEASE_NOTES.md +23 -0
  9. data/Rakefile +69 -0
  10. data/da_funk.gemspec +31 -0
  11. data/ext/da_funk/Makefile +5 -0
  12. data/ext/da_funk/extconf.rb +8 -0
  13. data/guides/sample_input_output.rb +14 -0
  14. data/guides/sample_message_iso8583.rb +14 -0
  15. data/guides/sample_network_gprs.rb +26 -0
  16. data/guides/sample_read_magnect_card.rb +8 -0
  17. data/guides/sample_socket.rb +29 -0
  18. data/guides/sample_transaction.rb +23 -0
  19. data/guides/sample_transaction_download_application.rb +9 -0
  20. data/guides/sample_transaction_download_file.rb +6 -0
  21. data/guides/sample_transaction_download_parameter_file.rb +18 -0
  22. data/guides/sample_transaction_iso8583.rb +222 -0
  23. data/imgs/daft-punk-da-funk.jpg +0 -0
  24. data/lib/da_funk/rake_task.rb +129 -0
  25. data/lib/da_funk/test.rb +87 -0
  26. data/lib/da_funk.rb +39 -0
  27. data/lib/device/application.rb +41 -0
  28. data/lib/device/audio.rb +17 -0
  29. data/lib/device/crypto.rb +52 -0
  30. data/lib/device/display.rb +47 -0
  31. data/lib/device/helper.rb +161 -0
  32. data/lib/device/io.rb +86 -0
  33. data/lib/device/magnetic.rb +79 -0
  34. data/lib/device/network.rb +192 -0
  35. data/lib/device/notification.rb +116 -0
  36. data/lib/device/notification_callback.rb +47 -0
  37. data/lib/device/notification_event.rb +29 -0
  38. data/lib/device/params_dat.rb +119 -0
  39. data/lib/device/printer.rb +35 -0
  40. data/lib/device/runtime.rb +22 -0
  41. data/lib/device/setting.rb +63 -0
  42. data/lib/device/support.rb +28 -0
  43. data/lib/device/system.rb +61 -0
  44. data/lib/device/transaction/download.rb +268 -0
  45. data/lib/device/transaction/emv.rb +45 -0
  46. data/lib/device/transaction/iso.rb +75 -0
  47. data/lib/device/version.rb +11 -0
  48. data/lib/device/walk.rb +8 -0
  49. data/lib/device.rb +28 -0
  50. data/lib/ext/kernel.rb +9 -0
  51. data/lib/file_db.rb +47 -0
  52. data/lib/iso8583/bitmap.rb +114 -0
  53. data/lib/iso8583/codec.rb +197 -0
  54. data/lib/iso8583/exception.rb +4 -0
  55. data/lib/iso8583/field.rb +90 -0
  56. data/lib/iso8583/fields.rb +171 -0
  57. data/lib/iso8583/message.rb +455 -0
  58. data/lib/iso8583/util.rb +91 -0
  59. data/lib/iso8583/version.rb +6 -0
  60. data/lib/serfx/commands.rb +191 -0
  61. data/lib/serfx/connection.rb +160 -0
  62. data/lib/serfx/exceptions.rb +5 -0
  63. data/lib/serfx/response.rb +28 -0
  64. data/lib/serfx.rb +27 -0
  65. data/lib/version.rb +5 -0
  66. data/lib/zip.rb +29 -0
  67. data/test/integration/getc_test.rb +6 -0
  68. data/test/integration/mrb_eval_test.rb +36 -0
  69. data/test/integration/notification_test.rb +20 -0
  70. data/test/integration/params_dat_test.rb +11 -0
  71. data/test/test_helper.rb +18 -0
  72. data/test/unit/device/display_test.rb +43 -0
  73. data/test/unit/device/helper_test.rb +61 -0
  74. data/test/unit/device/notification_callback_test.rb +6 -0
  75. data/test/unit/device/notification_event_test.rb +73 -0
  76. data/test/unit/device/notification_test.rb +21 -0
  77. data/utils/command_line_platform.rb +67 -0
  78. data/utils/test_run.rb +3 -0
  79. metadata +177 -0
@@ -0,0 +1,6 @@
1
+ # -*- mode: ruby; encoding: utf-8; tab-width: 2; indent-tabs-mode: nil -*-
2
+
3
+ module ISO8583
4
+ VERSION = "0.1.5.a"
5
+ end
6
+
@@ -0,0 +1,191 @@
1
+ module Serfx
2
+ # Implements all of Serf's rpc commands using
3
+ # Serfx::Connection#request method
4
+ module Commands
5
+ # performs initial hanshake of an RPC session. Handshake has to be the
6
+ # first command to be invoked during an RPC session.
7
+ #
8
+ # @return [Response]
9
+ def handshake
10
+ tcp_send(:handshake, 'Version' => 1)
11
+ read_response(:handshake)
12
+ end
13
+
14
+ # authenticate against the serf agent. if RPC credentials are setup, then
15
+ # `auth` has to be second command, immediately after `handshake`.
16
+ #
17
+ # @return [Response]
18
+ def auth
19
+ tcp_send(:auth, 'AuthKey' => @authkey)
20
+ read_response(:auth)
21
+ end
22
+ # fires an user event
23
+ #
24
+ # @param name [String] a string representing name of the event
25
+ # @param payload [String] payload, default is nil
26
+ # @param coalesce [Boolena] whether serf should coalesce events within
27
+ # same name during similar time frame
28
+ # @return [Response]
29
+ def event(name, payload = nil, coalesce = true)
30
+ event = {
31
+ 'Name' => name,
32
+ 'Coalesce' => coalesce
33
+ }
34
+ event['Payload'] = payload unless payload.nil?
35
+ request(:event, event)
36
+ end
37
+
38
+ # force a failed node to leave the cluster
39
+ #
40
+ # @param node [String] name of the failed node
41
+ # @return [Response]
42
+ def force_leave(node)
43
+ request(:force_leave, 'Node' => node)
44
+ end
45
+
46
+ # join an existing cluster.
47
+ #
48
+ # @param existing [Array] an array of existing serf agents
49
+ # @param replay [Boolean] Whether events should be replayed upon joining
50
+ # @return [Response]
51
+ def join(existing, replay = false)
52
+ request(:join, 'Existing' => existing, 'Replay' => replay)
53
+ end
54
+
55
+ # obtain the list of existing members
56
+ #
57
+ # @return [Response]
58
+ def members
59
+ request(:members)
60
+ end
61
+
62
+ # obatin the list of cluster members, filtered by tags.
63
+ #
64
+ # @param tags [Array] an array of tags for filter
65
+ # @param status [Boolean] filter members based on their satatus
66
+ # @param name [String] filter based on exact name or pattern.
67
+ #
68
+ # @return [Response]
69
+ def members_filtered(tags, status = 'alive', name = nil)
70
+ filter = {
71
+ 'Tags' => tags,
72
+ 'Status' => status
73
+ }
74
+ filter['Name'] = name unless name.nil?
75
+ request(:members_filtered, filter)
76
+ end
77
+
78
+ # alter the tags on a Serf agent while it is running. A member-update
79
+ # event will be triggered immediately to notify the other agents in the
80
+ # cluster of the change. The tags command can add new tags, modify
81
+ # existing tags, or delete tags
82
+ #
83
+ # @param tags [Hash] a hash representing tags as key-value pairs
84
+ # @param delete_tags [Array] an array of tags to be deleted
85
+ # @return [Response]
86
+ def tags(tags, delete_tags = [])
87
+ request(:tags, 'Tags' => tags, 'DeleteTags' => delete_tags)
88
+ end
89
+
90
+ # subscribe to a stream of all events matching a given type filter.
91
+ # Events will continue to be sent until the stream is stopped
92
+ #
93
+ # @param types [String] comma separated list of events
94
+ # @return [Thread, Response]
95
+ def stream(types, &block)
96
+ res = request(:stream, {'Type' => types})
97
+ loop do
98
+ header, ev = read_data(self.stream_timeout)
99
+ check_rpc_error!(header)
100
+ break unless fiber_yield!(ev)
101
+ end
102
+ res
103
+ end
104
+
105
+ # monitor is similar to the stream command, but instead of events it
106
+ # subscribes the channel to log messages from the agent
107
+ #
108
+ # @param loglevel [String]
109
+ # @return [Response]
110
+ def monitor(loglevel = 'debug')
111
+ request(:monitor, 'LogLevel' => loglevel.upcase)
112
+ end
113
+
114
+ # stop is used to stop either a stream or monitor
115
+ def stop(sequence_number)
116
+ tcp_send(:stop, 'Stop' => sequence_number)
117
+ end
118
+
119
+ # leave is used trigger a graceful leave and shutdown of the current agent
120
+ #
121
+ # @return [Response]
122
+ def leave
123
+ request(:leave)
124
+ end
125
+
126
+ # query is used to issue a new query
127
+ #
128
+ # @param name [String] name of the query
129
+ # @param payload [String] payload for this query event
130
+ # @param opts [Hash] additional query options
131
+ # @return [Response]
132
+ def query(name, payload, opts = {}, &block)
133
+ params = { 'Name' => name, 'Payload' => payload }
134
+ params.merge!(opts)
135
+ res = request(:query, params)
136
+ loop do
137
+ header, ev = read_data
138
+ check_rpc_error!(header)
139
+ break unless fiber_yield!(ev)
140
+ end
141
+ res
142
+ end
143
+
144
+ # respond is used with `stream` to subscribe to queries and then respond.
145
+ #
146
+ # @param id [Integer] an opaque value that is assigned by the IPC layer
147
+ # @param payload [String] payload for the response event
148
+ # @return [Response]
149
+ def respond(id, payload)
150
+ request(:respond, 'ID' => id, 'Payload' => payload)
151
+ end
152
+
153
+ # install a new encryption key onto the cluster's keyring
154
+ #
155
+ # @param key [String] 16 bytes of base64-encoded data.
156
+ # @return [Response]
157
+ def install_key(key)
158
+ request(:install_key, 'Key' => key)
159
+ end
160
+
161
+ # change the primary key, which is used to encrypt messages
162
+ #
163
+ # @param key [String] 16 bytes of base64-encoded data.
164
+ # @return [Response]
165
+ def use_key(key)
166
+ request(:use_key, 'Key' => key)
167
+ end
168
+
169
+ # remove a key from the cluster's keyring
170
+ #
171
+ # @param key [String] 16 bytes of base64-encoded data.
172
+ # @return [Response]
173
+ def remove_key(key)
174
+ request(:remove_key, 'Key' => key)
175
+ end
176
+
177
+ # return a list of all encryption keys currently in use on the cluster
178
+ #
179
+ # @return [Response]
180
+ def list_keys
181
+ request(:list_keys)
182
+ end
183
+
184
+ # obtain stats about the agent(same as info command)
185
+ #
186
+ # @return [Response]
187
+ def stats
188
+ request(:stats)
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,160 @@
1
+ module Serfx
2
+ # This class wraps the low level msgpack data transformation and tcp
3
+ # communication for the RPC session. methods in this module are used to
4
+ # implement the actual RPC commands available via [Commands]
5
+ class Connection
6
+ MAX_MESSAGE_SIZE = 1024
7
+ DEFAULT_TIMEOUT = 15
8
+ COMMANDS = {
9
+ handshake: [:header],
10
+ auth: [:header],
11
+ event: [:header],
12
+ force_leave: [:header],
13
+ join: [:header, :body],
14
+ members: [:header, :body],
15
+ members_filtered: [:header, :body],
16
+ tags: [:header],
17
+ stream: [:header],
18
+ monitor: [:header],
19
+ stop: [:header],
20
+ leave: [:header],
21
+ query: [:header],
22
+ respond: [:header],
23
+ install_key: [:header, :body],
24
+ use_key: [:header, :body],
25
+ remove_key: [:header, :body],
26
+ list_keys: [:header, :body],
27
+ stats: [:header, :body]
28
+ }
29
+
30
+ include Serfx::Commands
31
+
32
+ attr_reader :host, :port, :seq, :socket, :socket_tcp, :socket_block, :timeout, :stream_timeout
33
+
34
+ def close
35
+ @socket_tcp.close
36
+ @socket.close
37
+ end
38
+
39
+ def closed?
40
+ @socket_tcp.closed?
41
+ end
42
+
43
+ # @param opts [Hash] Specify the RPC connection details
44
+ # @option opts [TCPSocket] :socket_tcp Socket
45
+ # @option opts [SSL] :socket Socket SSL or normal tcp socket
46
+ # @option opts [Fixnum] :timeout Timeout in seconds to wait for a event and return Fiber
47
+ # @option opts [Symbol] :authkey encryption key for RPC communication
48
+ # @option opts [Block] :socket_block Callback to create socket if socket was closed, should return [socket, socket_tcp]
49
+ def initialize(opts = {})
50
+ if @socket_block = opts[:socket_block]
51
+ @socket, @socket_tcp = @socket_block.call
52
+ else
53
+ @socket = opts[:socket]
54
+ @socket_tcp = opts[:socket_tcp]
55
+ end
56
+ @timeout = opts[:timeout] || DEFAULT_TIMEOUT
57
+ @stream_timeout = opts[:stream_timeout] || DEFAULT_TIMEOUT
58
+ @seq = 0
59
+ @authkey = opts[:authkey]
60
+ @requests = {}
61
+ @responses = {}
62
+ end
63
+
64
+ # read data from tcp socket and pipe it through msgpack unpacker for
65
+ # deserialization
66
+ #
67
+ # @return [Hash]
68
+ def read_data(read_timeout = self.timeout)
69
+ buf = read_buffer(read_timeout)
70
+ return if buf.nil?
71
+
72
+ # TODO Check first and second(header and body) packet size
73
+ first_packet, second_packet = buf.split("\x85")
74
+ if second_packet.nil?
75
+ [MessagePack.unpack(first_packet), nil]
76
+ else
77
+ [MessagePack.unpack(first_packet), MessagePack.unpack("\x85" + second_packet)]
78
+ end
79
+ end
80
+
81
+ def read_buffer(read_timeout)
82
+ time_timeout = Time.now + read_timeout
83
+ loop do
84
+ bytes = socket.bytes_available
85
+ return socket.read(bytes) if bytes > 0
86
+ break unless time_timeout > Time.now
87
+ sleep 1
88
+ end
89
+ nil
90
+ end
91
+
92
+ # takes raw RPC command name and an optional request body
93
+ # and convert them to msgpack encoded data and then send
94
+ # over tcp
95
+ #
96
+ # @param command [String] RPC command name
97
+ # @param body [Hash] request body of the RPC command
98
+ #
99
+ # @return [Integer]
100
+ def tcp_send(command, body = nil)
101
+ @seq += 1
102
+ header = {
103
+ 'Command' => command.to_s.gsub('_', '-'),
104
+ 'Seq' => seq
105
+ }
106
+ buff = MessagePack::Packer.new
107
+ buff.write(header)
108
+ buff.write(body) unless body.nil?
109
+ res = socket.write(buff.to_str)
110
+ @requests[seq] = { header: header, ack?: false }
111
+ seq
112
+ end
113
+
114
+ # checks if the RPC response header has `error` field popular or not
115
+ # raises [RPCError] exception if error string is not empty
116
+ #
117
+ # @param header [Hash] RPC response header as hash
118
+ def check_rpc_error!(header)
119
+ if header
120
+ raise RPCError, header['Error'] unless header['Error'].empty?
121
+ end
122
+ end
123
+
124
+ # read data from the tcp socket. and convert it to a [Response] object
125
+ #
126
+ # @param command [String] RPC command name for which response will be read
127
+ # @return [Response]
128
+ def read_response(command, read_timeout = self.timeout)
129
+ header, body = read_data(read_timeout)
130
+ check_rpc_error!(header)
131
+ if COMMANDS[command].include?(:body)
132
+ Response.new(header, body)
133
+ else
134
+ Response.new(header)
135
+ end
136
+ end
137
+
138
+ # make an RPC request against the serf agent
139
+ #
140
+ # @param command [String] name of the RPC command
141
+ # @param body [Hash] an optional request body for the RPC command
142
+ # @return [Response]
143
+ def request(command, body = nil, read_timeout = self.timeout)
144
+ tcp_send(command, body)
145
+ read_response(command, read_timeout)
146
+ end
147
+
148
+ def fiber_yield!(ev)
149
+ if Fiber.yield(ev) == "close"
150
+ self.close
151
+ false
152
+ elsif self.closed?
153
+ false
154
+ else
155
+ true
156
+ end
157
+ end
158
+ end
159
+ end
160
+
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module Serfx
4
+ class RPCError < RuntimeError; end
5
+ end
@@ -0,0 +1,28 @@
1
+ module Serfx
2
+ # Store agent rpc response data
3
+ # All RPC responses in Serf composed of an header and an optional
4
+ # body.
5
+ #
6
+ class Response
7
+ # Header is composed of two sub-parts
8
+ # - Seq : an integer representing the original request
9
+ # - Error: a string that represent whether the request made, was
10
+ # successfull or no. For all successful RPC requests, Error should
11
+ # be an empty string
12
+ #
13
+ # `{"Seq": 0, "Error": ""}`
14
+ #
15
+ Header = Struct.new(:seq, :error)
16
+ attr_reader :header, :body
17
+
18
+ # Constructs a response object from a given header and body.
19
+ #
20
+ # @param header [Hash] header of the response as hash
21
+ # @param body [Hash] body of the response as hash
22
+ def initialize(header, body = nil)
23
+ @header = Header.new(header['Seq'], header['Error']) if header
24
+ @body = body
25
+ end
26
+ end
27
+ end
28
+
data/lib/serfx.rb ADDED
@@ -0,0 +1,27 @@
1
+
2
+ module Serfx
3
+ # Creates a serf rpc connection, performs handshake and auth
4
+ # (if authkey is supplied). If a block is provided, the connection
5
+ # object will be yield-ed and the connection will be closed after
6
+ # the block's execution, otherwise the connection will be returned
7
+ # Params:
8
+ # +opts+:: An optional hash which can have following keys:
9
+ # * host => Serf host's rpc bind address (127.0.0.1 by default)
10
+ # * port => Serf host's rpc port (7373 by default)
11
+ # * authkey => Encryption key for RPC communiction
12
+ #
13
+ # @return value of the block evaluation or the connection object
14
+ def self.connect(opts = {})
15
+ conn = Serfx::Connection.new(opts)
16
+ conn.handshake
17
+ conn.auth if opts.key?(:authkey)
18
+ res = nil
19
+ if block_given?
20
+ res = yield conn
21
+ conn.close unless conn.closed?
22
+ res
23
+ else
24
+ conn
25
+ end
26
+ end
27
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+
2
+ class Device
3
+ API_VERSION="0.4.4"
4
+ end
5
+
data/lib/zip.rb ADDED
@@ -0,0 +1,29 @@
1
+ module Zip
2
+ def self.compress(*args)
3
+ Miniz.zip(*args)
4
+ end
5
+
6
+ def self.uncompress(filezip, path = ".")
7
+ dir = "#{path}/#{filezip.split(".")[0]}"
8
+ clean(dir)
9
+ Miniz.unzip(filezip, path)
10
+ end
11
+
12
+ def self.clean(dir)
13
+ # TODO Refactor file check
14
+ if Dir.exist?(dir)
15
+ files = Dir.entries(dir)
16
+ if (files.size > 2)
17
+ files[2..-1].each do |file|
18
+ if File.file?("#{dir}/#{file}")
19
+ File.delete("#{dir}/#{file}")
20
+ else
21
+ Dir.delete("#{dir}/#{file}")
22
+ end
23
+ end
24
+ end
25
+ Dir.delete(dir)
26
+ end
27
+ Dir.mkdir(dir)
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+
2
+ class GetcTest < DaFunk::Test.case
3
+ def test_getc
4
+ assert_equal "a", getc(1000)
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+
2
+ class MrbEvalTest < DaFunk::Test.case
3
+ def test_socket
4
+ Device::Setting.environment = "staging"
5
+ Device::Setting.host = Device::Setting::HOST_STAGING
6
+ Device::Setting.company_name = "pc1"
7
+ Device::Setting.logical_number = "1234"
8
+
9
+ Device::Notification.start
10
+ Device::Notification.check
11
+
12
+ http = SimpleHttp.new('http', 'http://google.com', 443)
13
+ http.socket = Device::Network.walk_socket
14
+ assert_equal 302, http.get('/').code
15
+
16
+ command =<<EOF
17
+ require 'da_funk'
18
+ require 'da_funk/simplehttp'
19
+ require '../utils/command_line_platform.rb'
20
+ Device::Setting.environment = "staging"
21
+ Device::Setting.host = Device::Setting::HOST_STAGING
22
+ Device::Setting.company_name = "pc1"
23
+ Device::Setting.logical_number = "1234"
24
+
25
+ Device::Network.socket = nil
26
+ http = SimpleHttp.new('http', 'http://google.com', 80)
27
+ http.socket = Device::Network.walk_socket
28
+ response = http.get('/')
29
+ Device::Network.socket = nil
30
+ response.code
31
+ EOF
32
+ command << " \n; mrb_eval(#{command.inspect})"
33
+
34
+ assert_equal 302, mrb_eval(command)
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+
2
+ class NotificationTest < DaFunk::Test.case
3
+ def test_notification
4
+ Device::Setting.company_name = "pc1"
5
+ Device::Setting.logical_number = "0101"
6
+ notification = Device::Notification.new
7
+ assert_equal nil, notification.check
8
+ notification.check
9
+ notification.check
10
+ assert notification.close
11
+ assert notification.closed?
12
+ notification = Device::Notification.new
13
+ assert_equal nil, notification.check
14
+ notification.check
15
+ notification.check
16
+ notification.close
17
+ assert notification.closed?
18
+ end
19
+ end
20
+
@@ -0,0 +1,11 @@
1
+
2
+ class ParamsDatTest < DaFunk::Test.case
3
+ def test_parse_apps
4
+ Device::Setting.environment = "staging"
5
+ Device::Setting.host = Device::Setting::HOST_STAGING
6
+ Device::Setting.company_name = "pc1"
7
+ Device::Setting.logical_number = "1410"
8
+ Device::ParamsDat.update_apps
9
+ Device::ParamsDat.application_menu
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+
2
+ if Object.const_defined?(:MTest)
3
+ ROOT_PATH = File.expand_path("./")
4
+ APP_NAME = File.basename(File.dirname(ROOT_PATH))
5
+
6
+ $LOAD_PATH.unshift "./#{APP_NAME}"
7
+
8
+ require 'da_funk'
9
+
10
+ DaFunk::Test.configure do |t|
11
+ t.root_path = ROOT_PATH
12
+ end
13
+ else
14
+ require "./lib/da_funk.rb"
15
+ require "test/unit"
16
+ require "./test/fixtures/platform.rb"
17
+ end
18
+
@@ -0,0 +1,43 @@
1
+
2
+ class DisplayTest < DaFunk::Test.case
3
+ def test_display_print
4
+ assert_equal nil, Device::Display.print("test")
5
+ assert_equal nil, Device::Display.print("test", 0)
6
+ assert_equal nil, Device::Display.print("test", 0, 0)
7
+ end
8
+
9
+ def test_display_print_line
10
+ assert_equal nil, Device::Display.print_line("test")
11
+ assert_equal nil, Device::Display.print_line("test", 0)
12
+ assert_equal nil, Device::Display.print_line("test", 0, 0)
13
+ end
14
+
15
+ def test_clear
16
+ assert_equal nil, Device::Display.clear
17
+ assert_equal nil, Device::Display.clear(2)
18
+ end
19
+
20
+ def test_print_bitmap
21
+ assert_raise File::FileError do
22
+ Device::Display.print_bitmap("test")
23
+ end
24
+ end
25
+
26
+ def test_kernel_print_line
27
+ assert_equal nil, print_line("test")
28
+ assert_equal nil, print_line("test", 0)
29
+ assert_equal nil, print_line("test", 0, 0)
30
+ end
31
+
32
+ def test_kernel_print
33
+ assert_equal nil, print("test")
34
+ assert_equal nil, print("test", 0)
35
+ assert_equal nil, print("test", 0, 0)
36
+ end
37
+
38
+ def test_kernel_puts
39
+ assert_equal nil, puts("test")
40
+ assert_equal nil, puts("test", 0)
41
+ assert_equal nil, puts("test", 0, 0)
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ class HelperKlass
2
+ include Device::Helper
3
+ end
4
+
5
+ class HelperTest < DaFunk::Test.case
6
+ def setup
7
+ @helper = HelperKlass.new
8
+ end
9
+
10
+ def test_number_to_currency_basic
11
+ assert_equal "0.00", @helper.number_to_currency("")
12
+ assert_equal "0.01", @helper.number_to_currency("1")
13
+ assert_equal "0.10", @helper.number_to_currency("10")
14
+ assert_equal "0.01", @helper.number_to_currency("01")
15
+ assert_equal "1.00", @helper.number_to_currency("100")
16
+ assert_equal "10.00", @helper.number_to_currency("1000")
17
+ end
18
+
19
+ def test_number_to_currency_separator
20
+ assert_equal "100.00", @helper.number_to_currency("10000", {:separator => "."})
21
+ assert_equal "100,00", @helper.number_to_currency("10000", {:separator => ","})
22
+ end
23
+
24
+ def test_number_to_currency_delimiter
25
+ assert_equal "1.000.00", @helper.number_to_currency("100000", {:delimiter => "."})
26
+ assert_equal "1,000.00", @helper.number_to_currency("100000", {:delimiter => ","})
27
+ end
28
+
29
+ def test_number_to_currency_precision
30
+ assert_equal "100.00", @helper.number_to_currency("10000", {:precision => 2})
31
+ assert_equal "10.000", @helper.number_to_currency("10000", {:precision => 3})
32
+ assert_equal "1,000.000", @helper.number_to_currency("1000000", {:precision => 3})
33
+ end
34
+
35
+ def test_number_to_currency_fixnum
36
+ assert_equal "100.00", @helper.number_to_currency(10000, {:precision => 2})
37
+ assert_equal "10.000", @helper.number_to_currency(10000, {:precision => 3})
38
+ assert_equal "1,000.000", @helper.number_to_currency(1000000, {:precision => 3})
39
+ end
40
+
41
+ def test_number_to_currency_float
42
+ assert_equal "100.00", @helper.number_to_currency(100.0, {:precision => 2})
43
+ assert_equal "100.000", @helper.number_to_currency(100.0, {:precision => 3})
44
+ assert_equal "10,000.000", @helper.number_to_currency(10000.0, {:precision => 3})
45
+ end
46
+
47
+ def test_number_to_currency_basic
48
+ assert_equal "U$: 0.00", @helper.number_to_currency("", {:label => "U$: "})
49
+ assert_equal "U$: 0.01", @helper.number_to_currency("1", {:label => "U$: "})
50
+ assert_equal "U$: 0.10", @helper.number_to_currency("10", {:label => "U$: "})
51
+ assert_equal "U$: 0.01", @helper.number_to_currency("01", {:label => "U$: "})
52
+ assert_equal "U$: 1.00", @helper.number_to_currency("100", {:label => "U$: "})
53
+ assert_equal "U$: 10.00", @helper.number_to_currency("1000", {:label => "U$: "})
54
+ end
55
+
56
+ def test_helper_include_scope
57
+ assert HelperKlass.methods.include? :attach
58
+ assert HelperKlass.new.methods.include? :attach
59
+ end
60
+ end
61
+
@@ -0,0 +1,6 @@
1
+
2
+ class NotificationCallbackTest < DaFunk::Test.case
3
+ def test_true
4
+ assert true
5
+ end
6
+ end