win32-clipboard 0.5.2 → 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 +7 -0
- data/CHANGES +91 -81
- data/MANIFEST +12 -8
- data/README +112 -112
- data/Rakefile +40 -15
- data/examples/clipboard_test.rb +28 -28
- data/lib/win32/clipboard.rb +414 -412
- data/lib/win32/html_clipboard.rb +232 -0
- data/lib/win32/windows/constants.rb +10 -0
- data/lib/win32/windows/functions.rb +56 -0
- data/lib/win32/windows/structs.rb +43 -0
- data/test/test_clipboard.rb +155 -135
- data/test/test_html_clipboard.rb +50 -0
- data/win32-clipboard.gemspec +26 -30
- metadata +78 -46
@@ -0,0 +1,232 @@
|
|
1
|
+
# The Win32 module serves as a namespace only.
|
2
|
+
#
|
3
|
+
module Win32
|
4
|
+
|
5
|
+
# The HtmlClipboard class is a subclass of Clipboard that explicitly
|
6
|
+
# handles text in HTML format.
|
7
|
+
#
|
8
|
+
class HtmlClipboard < Clipboard
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Marker block output
|
13
|
+
#--
|
14
|
+
# Version: Version of the clipboard.
|
15
|
+
#
|
16
|
+
# StartHTML: bytecount from the beginning of the clipboard to the
|
17
|
+
# start of the context, or -1 if no context.
|
18
|
+
#
|
19
|
+
# EndHTML: bytecount from the beginning of the clipboard to the end
|
20
|
+
# of the context, or -1 if no context.
|
21
|
+
#
|
22
|
+
# StartFragment: bytecount from the beginning of the clipboard to
|
23
|
+
# the start of the fragment.
|
24
|
+
#
|
25
|
+
# EndFragment: bytecount from the beginning of the clipboard to the
|
26
|
+
# end of the fragment.
|
27
|
+
#
|
28
|
+
# StartSelection: bytecount from the beginning of the clipboard to
|
29
|
+
# the start of the selection.
|
30
|
+
#
|
31
|
+
# EndSelection: bytecount from the beginning of the clipboard to the
|
32
|
+
# end of the selection.
|
33
|
+
#
|
34
|
+
MARKER_BLOCK_OUTPUT =
|
35
|
+
"Version:1.0\r\n" \
|
36
|
+
"StartHTML:%09d\r\n" \
|
37
|
+
"EndHTML:%09d\r\n" \
|
38
|
+
"StartFragment:%09d\r\n" \
|
39
|
+
"EndFragment:%09d\r\n" \
|
40
|
+
"StartSelection:%09d\r\n" \
|
41
|
+
"EndSelection:%09d\r\n" \
|
42
|
+
"SourceURL:%s\r\n"
|
43
|
+
|
44
|
+
# Extended marker block
|
45
|
+
MARKER_BLOCK_EX =
|
46
|
+
'Version:(\S+)\s+' \
|
47
|
+
'StartHTML:(\d+)\s+' \
|
48
|
+
'EndHTML:(\d+)\s+' \
|
49
|
+
'StartFragment:(\d+)\s+' \
|
50
|
+
'EndFragment:(\d+)\s+' \
|
51
|
+
'StartSelection:(\d+)\s+' \
|
52
|
+
'EndSelection:(\d+)\s+' \
|
53
|
+
'SourceURL:(\S+)'
|
54
|
+
|
55
|
+
# Regular expression for extended marker block
|
56
|
+
MARKER_BLOCK_EX_RE = Regexp.new(MARKER_BLOCK_EX, Regexp::MULTILINE) # :nodoc:
|
57
|
+
|
58
|
+
# Standard marker block
|
59
|
+
MARKER_BLOCK =
|
60
|
+
'Version:(\S+)\s+' \
|
61
|
+
'StartHTML:(\d+)\s+' \
|
62
|
+
'EndHTML:(\d+)\s+' \
|
63
|
+
'StartFragment:(\d+)\s+' \
|
64
|
+
'EndFragment:(\d+)\s+' \
|
65
|
+
'SourceURL:(\S+)'
|
66
|
+
|
67
|
+
# Regular expression for the standard marker block
|
68
|
+
MARKER_BLOCK_RE = Regexp.new(MARKER_BLOCK, Regexp::MULTILINE)
|
69
|
+
|
70
|
+
# Default HTML body
|
71
|
+
DEFAULT_HTML_BODY =
|
72
|
+
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n" \
|
73
|
+
"<HTML><BODY><!--StartFragment-->%s<!--EndFragment--></BODY></HTML>"
|
74
|
+
|
75
|
+
public
|
76
|
+
|
77
|
+
# Clipboard format value
|
78
|
+
CF_HTML = RegisterClipboardFormat("HTML Format")
|
79
|
+
|
80
|
+
def initialize # :nodoc:
|
81
|
+
@html = nil
|
82
|
+
@fragment = nil
|
83
|
+
@selection = nil
|
84
|
+
@source = nil
|
85
|
+
@version = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns a boolean indicating whether or not the clipboard contains
|
89
|
+
# data in HTML format.
|
90
|
+
#
|
91
|
+
def self.html_format?
|
92
|
+
format_available?(CF_HTML)
|
93
|
+
end
|
94
|
+
|
95
|
+
# This method is nearly identical to the Clipboard.data method, but
|
96
|
+
# it decodes the data to preserve the HTML formatting.
|
97
|
+
#
|
98
|
+
def self.data
|
99
|
+
begin
|
100
|
+
self.open
|
101
|
+
if IsClipboardFormatAvailable(CF_HTML)
|
102
|
+
handle = GetClipboardData(CF_HTML)
|
103
|
+
size = GlobalSize(handle)
|
104
|
+
ptr = FFI::Pointer.new(:char, handle)
|
105
|
+
|
106
|
+
clip_data = decode_data(ptr.read_bytes(size))
|
107
|
+
else
|
108
|
+
clip_data = ''
|
109
|
+
end
|
110
|
+
ensure
|
111
|
+
self.close
|
112
|
+
end
|
113
|
+
clip_data
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns the block marker information for the HTML, or an empty
|
117
|
+
# string if there is no clipboard data.
|
118
|
+
#
|
119
|
+
def self.data_details
|
120
|
+
clip_data = data
|
121
|
+
string = ""
|
122
|
+
unless clip_data.empty?
|
123
|
+
string << "prefix=>>>#{@prefix}<<<END"
|
124
|
+
string << "version=>>>#{@version}<<<END"
|
125
|
+
string << "selection=>>>#{@selection}<<<END"
|
126
|
+
string << "fragment=>>>#{@fragment}<<<END"
|
127
|
+
string << "html=>>>#{@html}<<<END"
|
128
|
+
string << "source=>>>#{@source}<<<END"
|
129
|
+
end
|
130
|
+
string
|
131
|
+
end
|
132
|
+
|
133
|
+
# Put a well-formed fragment of HTML on the clipboard.
|
134
|
+
#
|
135
|
+
# The +selection+, if provided, must be a literal string within a
|
136
|
+
# fragment.
|
137
|
+
#
|
138
|
+
# The +html+ value, if provided, must be a well formed HTML document
|
139
|
+
# that textually contains a fragment and its required markers.
|
140
|
+
#
|
141
|
+
# The +source+, if provided, should include a scheme (file, http, or
|
142
|
+
# https) plus a file name. The default is file:// + __FILE__.
|
143
|
+
#
|
144
|
+
def self.set_data(fragment, selection=nil, html=nil, source=nil)
|
145
|
+
selection ||= fragment
|
146
|
+
html ||= DEFAULT_HTML_BODY % fragment
|
147
|
+
source ||= 'file://' + __FILE__
|
148
|
+
|
149
|
+
fragment_start = html.index(fragment)
|
150
|
+
fragment_end = fragment_start + fragment.length
|
151
|
+
selection_start = html.index(selection)
|
152
|
+
selection_end = selection_start + selection.length
|
153
|
+
|
154
|
+
clip_data = encode_data(
|
155
|
+
html,
|
156
|
+
fragment_start,
|
157
|
+
fragment_end,
|
158
|
+
selection_start,
|
159
|
+
selection_end,
|
160
|
+
source
|
161
|
+
)
|
162
|
+
|
163
|
+
self.open
|
164
|
+
EmptyClipboard()
|
165
|
+
|
166
|
+
# Global Allocate a movable piece of memory.
|
167
|
+
hmem = GlobalAlloc(GHND, clip_data.length + 4)
|
168
|
+
mem = GlobalLock(hmem)
|
169
|
+
mem.write_bytes(clip_data, 0, clip_data.size)
|
170
|
+
|
171
|
+
clip_data2 = fragment.gsub(/<[^>]+?>/,'')
|
172
|
+
hmem2 = GlobalAlloc(GHND, clip_data2.length + 4)
|
173
|
+
mem2 = GlobalLock(hmem2)
|
174
|
+
mem2.write_bytes(clip_data2, 0, clip_data2.size)
|
175
|
+
|
176
|
+
# Set the new data
|
177
|
+
begin
|
178
|
+
if SetClipboardData(CF_HTML, hmem) == 0
|
179
|
+
raise SystemCallError.new('SetClipboardData', FFI.errno)
|
180
|
+
end
|
181
|
+
|
182
|
+
if SetClipboardData(CF_TEXT, hmem2) == 0
|
183
|
+
raise SystemCallError.new('SetClipboardData', FFI.errno)
|
184
|
+
end
|
185
|
+
ensure
|
186
|
+
GlobalFree(hmem)
|
187
|
+
GlobalFree(hmem2)
|
188
|
+
self.close
|
189
|
+
end
|
190
|
+
self
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
# Encode the data markers into the HTML data
|
196
|
+
def self.encode_data(html,frag_start,frag_end,select_start,select_end,src)
|
197
|
+
dummy_prefix = MARKER_BLOCK_OUTPUT % [0,0,0,0,0,0,src]
|
198
|
+
len_prefix = dummy_prefix.length
|
199
|
+
prefix = MARKER_BLOCK_OUTPUT % [len_prefix, html.length + len_prefix,
|
200
|
+
frag_start + len_prefix, frag_end + len_prefix,
|
201
|
+
select_start + len_prefix, select_end + len_prefix, src]
|
202
|
+
prefix + html
|
203
|
+
end
|
204
|
+
|
205
|
+
# Decode the given string to figure out the details of the HTML
|
206
|
+
# that's on the string.
|
207
|
+
#--
|
208
|
+
# Try the extended format first, which has an explicit selection.
|
209
|
+
# If that fails, try the version without a selection.
|
210
|
+
#
|
211
|
+
def self.decode_data(src)
|
212
|
+
if (matches = MARKER_BLOCK_EX_RE.match(src))
|
213
|
+
@prefix = matches[0]
|
214
|
+
@version = matches[1]
|
215
|
+
@html = src[matches[2].to_i ... matches[3].to_i]
|
216
|
+
@fragment = src[matches[4].to_i ... matches[5].to_i]
|
217
|
+
@selection = src[matches[6].to_i ... matches[7].to_i]
|
218
|
+
@source = matches[8]
|
219
|
+
elsif (matches = MARKER_BLOCK_RE.match(src))
|
220
|
+
@prefix = matches[0]
|
221
|
+
@version = matches[1]
|
222
|
+
@html = src[matches[2].to_i ... matches[3].to_i]
|
223
|
+
@fragment = src[matches[4].to_i ... matches[5].to_i]
|
224
|
+
@source = matches[6]
|
225
|
+
@selection = @fragment
|
226
|
+
else
|
227
|
+
raise 'failed to match block markers'
|
228
|
+
end
|
229
|
+
@fragment
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Windows
|
4
|
+
module Functions
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
typedef :uintptr_t, :hglobal
|
8
|
+
typedef :uintptr_t, :hwnd
|
9
|
+
typedef :uintptr_t, :handle
|
10
|
+
typedef :uintptr_t, :hmenu
|
11
|
+
typedef :uintptr_t, :hdrop
|
12
|
+
typedef :uintptr_t, :hinstance
|
13
|
+
typedef :ulong, :dword
|
14
|
+
|
15
|
+
callback :wnd_proc, [:hwnd, :uint, :long, :long], :long
|
16
|
+
|
17
|
+
ffi_lib :kernel32
|
18
|
+
|
19
|
+
attach_function :GlobalAlloc, [:uint, :size_t], :hglobal
|
20
|
+
attach_function :GlobalFree, [:hglobal], :hglobal
|
21
|
+
attach_function :GlobalLock, [:hglobal], :pointer
|
22
|
+
attach_function :GlobalSize, [:hglobal], :size_t
|
23
|
+
attach_function :GlobalUnlock, [:hglobal], :bool
|
24
|
+
|
25
|
+
ffi_lib :user32
|
26
|
+
|
27
|
+
attach_function :CloseClipboard, [], :bool
|
28
|
+
attach_function :CountClipboardFormats, [], :int
|
29
|
+
attach_function :CreateWindowEx, :CreateWindowExA, [:dword, :string, :string, :dword, :int, :int, :int, :int, :hwnd, :hmenu, :hinstance, :pointer], :hwnd
|
30
|
+
attach_function :DefWindowProc, :DefWindowProcA, [:hwnd, :uint, :uint, :uint], :long
|
31
|
+
attach_function :DispatchMessage, :DispatchMessageA, [:pointer], :uint
|
32
|
+
attach_function :EmptyClipboard, [], :bool
|
33
|
+
attach_function :EnumClipboardFormats, [:uint], :uint
|
34
|
+
attach_function :GetClipboardData, [:uint], :handle
|
35
|
+
attach_function :GetClipboardFormatName, :GetClipboardFormatNameA, [:uint, :pointer, :int], :int
|
36
|
+
attach_function :GetWindowLongPtr, :GetWindowLongPtrA, [:hwnd, :int], :long
|
37
|
+
attach_function :IsClipboardFormatAvailable, [:uint], :bool
|
38
|
+
attach_function :OpenClipboard, [:hwnd], :bool
|
39
|
+
attach_function :PeekMessage, :PeekMessageA, [:pointer, :hwnd, :uint, :uint, :uint], :bool
|
40
|
+
attach_function :PostMessage, :PostMessageA, [:hwnd, :uint, :uintptr_t, :uintptr_t], :bool
|
41
|
+
attach_function :RegisterClipboardFormat, :RegisterClipboardFormatA, [:string], :uint
|
42
|
+
attach_function :SetClipboardData, [:uint, :handle], :handle
|
43
|
+
attach_function :SetClipboardViewer, [:hwnd], :hwnd
|
44
|
+
attach_function :SetWindowLongPtr, :SetWindowLongPtrA, [:hwnd, :int, :uintptr_t], :long
|
45
|
+
attach_function :TranslateMessage, [:pointer], :bool
|
46
|
+
|
47
|
+
ffi_lib :shell32
|
48
|
+
|
49
|
+
attach_function :DragQueryFileA, [:hdrop, :uint, :pointer, :uint], :uint
|
50
|
+
|
51
|
+
ffi_lib :gdi32
|
52
|
+
|
53
|
+
attach_function :GetEnhMetaFileBits, [:handle, :uint, :pointer], :uint
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Windows
|
4
|
+
module Structs
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
typedef :uchar, :byte
|
8
|
+
typedef :ulong, :dword
|
9
|
+
typedef :ushort, :word
|
10
|
+
|
11
|
+
class RGBQUAD < FFI::Struct
|
12
|
+
layout(
|
13
|
+
:rgbBlue, :byte,
|
14
|
+
:rgbGreen, :byte,
|
15
|
+
:rgbRed, :byte,
|
16
|
+
:rgbReserved, :byte,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
class BITMAPINFOHEADER < FFI::Struct
|
21
|
+
layout(
|
22
|
+
:biSize, :dword,
|
23
|
+
:biWidth, :long,
|
24
|
+
:biHeight, :long,
|
25
|
+
:biPlanes, :word,
|
26
|
+
:biBitCount, :word,
|
27
|
+
:biCompression, :dword,
|
28
|
+
:biSizeImage, :dword,
|
29
|
+
:biXPelsPerMeter, :long,
|
30
|
+
:biYPelsPerMeter, :long,
|
31
|
+
:biClrUsed, :dword,
|
32
|
+
:biClrImportant, :dword
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
class BITMAPINFO < FFI::Struct
|
37
|
+
layout(
|
38
|
+
:bmiHeader, BITMAPINFOHEADER,
|
39
|
+
:bmiColor, [RGBQUAD, 1]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/test/test_clipboard.rb
CHANGED
@@ -1,135 +1,155 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
###########################################################################
|
3
|
+
# test_clipboard.rb
|
4
|
+
#
|
5
|
+
# Test suite for the win32-clipboard library. This will copy and remove
|
6
|
+
# data from your clipboard. If your current clipboard data is crucial to
|
7
|
+
# you, please save it first.
|
8
|
+
#
|
9
|
+
# You should run this test case via the 'rake test' task.
|
10
|
+
###########################################################################
|
11
|
+
require 'test-unit'
|
12
|
+
require 'win32/clipboard'
|
13
|
+
include Win32
|
14
|
+
|
15
|
+
class TC_Win32_ClipBoard < Test::Unit::TestCase
|
16
|
+
test "version is set to expected value" do
|
17
|
+
assert_equal('0.6.0', Clipboard::VERSION)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "data method basic functionality" do
|
21
|
+
assert_respond_to(Clipboard, :data)
|
22
|
+
assert_nothing_raised{ Clipboard.data }
|
23
|
+
assert_kind_of(String, Clipboard.data)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "data method requires proper format" do
|
27
|
+
assert_raise(TypeError){ Clipboard.data('test') }
|
28
|
+
assert_raise(NameError){ Clipboard.data(CF_FOO) }
|
29
|
+
end
|
30
|
+
|
31
|
+
test "get_data is an alias for data" do
|
32
|
+
assert_respond_to(Clipboard, :get_data)
|
33
|
+
assert_alias_method(Clipboard, :data, :get_data)
|
34
|
+
end
|
35
|
+
|
36
|
+
test "set_data basic functionality" do
|
37
|
+
assert_respond_to(Clipboard, :set_data)
|
38
|
+
assert_nothing_raised{ Clipboard.set_data('foo') }
|
39
|
+
end
|
40
|
+
|
41
|
+
test "set_data works with unicode text" do
|
42
|
+
assert_nothing_raised{
|
43
|
+
Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
test "set_data requires at least one argument" do
|
48
|
+
assert_raise(ArgumentError){ Clipboard.set_data }
|
49
|
+
end
|
50
|
+
|
51
|
+
test "set_data requires a valid data format" do
|
52
|
+
assert_raise(NameError){ Clipboard.set_data('foo', CF_FOO) }
|
53
|
+
end
|
54
|
+
|
55
|
+
test "set and get ascii data as expected" do
|
56
|
+
assert_nothing_raised{ Clipboard.set_data('foobar') }
|
57
|
+
assert_equal('foobar', Clipboard.data)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "set and get unicode data as expected" do
|
61
|
+
assert_nothing_raised{
|
62
|
+
Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
|
63
|
+
}
|
64
|
+
assert_equal('Ηελλας', Clipboard.data(Clipboard::UNICODETEXT))
|
65
|
+
end
|
66
|
+
|
67
|
+
test "empty method basic functionality" do
|
68
|
+
assert_respond_to(Clipboard, :empty)
|
69
|
+
assert_nothing_raised{ Clipboard.empty }
|
70
|
+
end
|
71
|
+
|
72
|
+
test "clear is an alias for empty" do
|
73
|
+
assert_respond_to(Clipboard, :clear)
|
74
|
+
assert_alias_method(Clipboard, :clear, :empty)
|
75
|
+
end
|
76
|
+
|
77
|
+
test "num_formats basic functionality" do
|
78
|
+
assert_respond_to(Clipboard, :num_formats)
|
79
|
+
assert_nothing_raised{ Clipboard.num_formats }
|
80
|
+
assert_kind_of(Fixnum, Clipboard.num_formats)
|
81
|
+
end
|
82
|
+
|
83
|
+
test "num_formats returns an expected value" do
|
84
|
+
assert_true(Clipboard.num_formats >= 0)
|
85
|
+
assert_true(Clipboard.num_formats < 1000)
|
86
|
+
end
|
87
|
+
|
88
|
+
test "num_formats does not accept any arguments" do
|
89
|
+
assert_raise(ArgumentError){ Clipboard.num_formats(true) }
|
90
|
+
end
|
91
|
+
|
92
|
+
test "register_format basic functionality" do
|
93
|
+
assert_respond_to(Clipboard, :register_format)
|
94
|
+
assert_nothing_raised{ Clipboard.register_format('Ruby') }
|
95
|
+
assert_kind_of(Integer, Clipboard.register_format('Ruby'))
|
96
|
+
end
|
97
|
+
|
98
|
+
test "register_format requires a string argument" do
|
99
|
+
assert_raises(TypeError){ Clipboard.register_format(1) }
|
100
|
+
end
|
101
|
+
|
102
|
+
test "formats method basic functionality" do
|
103
|
+
assert_respond_to(Clipboard, :formats)
|
104
|
+
assert_nothing_raised{ Clipboard.formats }
|
105
|
+
assert_kind_of(Hash, Clipboard.formats)
|
106
|
+
end
|
107
|
+
|
108
|
+
# TODO: Why do these fail?
|
109
|
+
#test "formats result contains expected values" do
|
110
|
+
# assert_true(Clipboard.formats.size > 0)
|
111
|
+
# assert_true(Clipboard.formats.include?(1))
|
112
|
+
#end
|
113
|
+
|
114
|
+
test "formats method does not accept any arguments" do
|
115
|
+
assert_raise(ArgumentError){ Clipboard.formats(true) }
|
116
|
+
end
|
117
|
+
|
118
|
+
test "format_available basic functionality" do
|
119
|
+
assert_respond_to(Clipboard, :format_available?)
|
120
|
+
assert_nothing_raised{ Clipboard.format_available?(1) }
|
121
|
+
end
|
122
|
+
|
123
|
+
test "format_available returns a boolean value" do
|
124
|
+
assert_boolean(Clipboard.format_available?(1))
|
125
|
+
end
|
126
|
+
|
127
|
+
test "format_name basic functionality" do
|
128
|
+
assert_respond_to(Clipboard, :format_name)
|
129
|
+
assert_nothing_raised{ Clipboard.format_name(1) }
|
130
|
+
end
|
131
|
+
|
132
|
+
test "format_name returns expected value" do
|
133
|
+
format = Clipboard.register_format('HTML Format')
|
134
|
+
assert_equal('HTML Format', Clipboard.format_name(format))
|
135
|
+
assert_nil(Clipboard.format_name(9999999))
|
136
|
+
end
|
137
|
+
|
138
|
+
test "format_name requires a numeric argument" do
|
139
|
+
assert_raise(TypeError){ Clipboard.format_name('foo') }
|
140
|
+
end
|
141
|
+
|
142
|
+
test "notify_change basic functionality" do
|
143
|
+
assert_respond_to(Clipboard, :notify_change)
|
144
|
+
end
|
145
|
+
|
146
|
+
test "expected constants are defined" do
|
147
|
+
assert_not_nil(Clipboard::TEXT)
|
148
|
+
assert_not_nil(Clipboard::OEMTEXT)
|
149
|
+
assert_not_nil(Clipboard::UNICODETEXT)
|
150
|
+
assert_not_nil(Clipboard::BITMAP)
|
151
|
+
assert_not_nil(Clipboard::DIB)
|
152
|
+
assert_not_nil(Clipboard::HDROP)
|
153
|
+
assert_not_nil(Clipboard::ENHMETAFILE)
|
154
|
+
end
|
155
|
+
end
|