1# coding: us-ascii
2
3begin
4  require 'win32ole'
5rescue LoadError
6end
7require 'test/unit'
8
9if defined?(WIN32OLE)
10  module CONST1
11  end
12  module CONST2
13  end
14
15  module TestCaseForDict
16    def test_convert_bignum
17      @dict1.add("a", 9999999999)
18      @dict1.add("b", 999999999)
19      @dict1.add("c", @dict1.item("b") * 10 + 9)
20      assert_equal(9999999999, @dict1.item("a"))
21      assert_equal(9999999999, @dict1.item("c"))
22    end
23    def test_add
24      @dict1.add("a", 1000)
25      assert_equal(1000, @dict1.item("a"))
26    end
27    def test_setproperty_equal_ended
28      @dict1.compareMode = 1
29      @dict1.add("one", 1)
30      assert_equal(1, @dict1.item("ONE"))
31      @dict2.add("one", 1)
32      assert_nil(@dict2.item("ONE"))
33      assert_equal(1, @dict2.item("one"))
34    end
35    def test_non_exist_property
36      assert_raise(WIN32OLERuntimeError) {
37        @dict1.unknown_property = 1
38      }
39    end
40
41    def test_raise_message
42      exc = assert_raise(WIN32OLERuntimeError) {
43        @dict1.add
44      }
45      assert_match(/^\(in OLE method `add': \)/, exc.message) #`
46
47      exc = assert_raise(WIN32OLERuntimeError) {
48        @dict1._invoke(1, [], [])
49      }
50      assert_match(/^\(in OLE method `<dispatch id:1>': \)/, exc.message) #`
51
52      exc = assert_raise(WIN32OLERuntimeError) {
53        @dict1.compareMode = -1
54      }
55      assert_match(/^\(in setting property `compareMode': \)/, exc.message) #`
56    end
57
58    def test_no_method_error
59      exc = assert_raise(NoMethodError) {
60          @dict1.non_exist_method
61      }
62      assert_match(/non_exist_method/, exc.message)
63    end
64
65    def test_ole_methods
66      methods = @dict1.ole_methods
67      mnames = methods.collect {|m|
68        m.name
69      }
70      assert(mnames.include?("Add"))
71    end
72
73    def test_ole_func_methods
74      methods = @dict1.ole_func_methods
75      mnames = methods.collect {|m|
76        m.name
77      }
78      assert(mnames.include?("Add"))
79    end
80
81    def test_ole_put_methods
82      methods = @dict1.ole_put_methods
83      mnames = methods.collect {|m|
84        m.name
85      }
86      assert(mnames.include?("CompareMode"))
87    end
88
89    def test_ole_get_methods
90      methods = @dict1.ole_get_methods
91      mnames = methods.collect {|m|
92        m.name
93      }
94      assert(mnames.include?("Count"))
95    end
96
97    def test_ole_mehtod_help
98      minfo = @dict1.ole_method_help("Add")
99      assert_equal(2, minfo.size_params)
100    end
101
102    def test_ole_typelib
103      tlib = @dict1.ole_typelib
104      assert_equal("Microsoft Scripting Runtime", tlib.name);
105    end
106
107    def test_each
108      @dict1.add("one", 1)
109      @dict1.add("two", 2)
110      i = 0
111      @dict1.keys.each do |item|
112        i += 1
113      end
114      assert_equal(2, i)
115    end
116
117    def test_bracket
118      @dict1.add("foo", "FOO")
119      assert_equal("FOO", @dict1.item("foo"))
120      assert_equal("FOO", @dict1["foo"])
121    end
122
123    def test_bracket_equal
124      @dict1.add("foo", "FOO")
125      @dict1["foo"] = "BAR"
126      assert_equal("BAR", @dict1["foo"])
127    end
128
129    def test_bracket_with_numkey
130      @dict1.add(1, "ONE")
131      @dict1.add(2, "two")
132      assert_equal("ONE", @dict1[1])
133      @dict1[2] = "TWO"
134      assert_equal("TWO", @dict1[2])
135    end
136
137    def test_invoke_with_array
138      @dict1.add("ary1", [1,2,3])
139      assert_equal([1,2,3], @dict1["ary1"])
140
141      @dict1.add("ary2", [[1,2,"a"], [3,4,"b"]])
142      assert_equal([[1,2,"a"], [3,4,"b"]], @dict1["ary2"])
143
144      @dict1.add("ary3", [[[1]]])
145      assert_equal([[[1]]], @dict1["ary3"])
146
147      @dict1.add("ary4", [[[1], [2], [3]], [[4], [5], [6]]])
148      assert_equal([[[1],[2], [3]], [[4], [5], [6]]], @dict1["ary4"])
149    end
150  end
151
152  class TestWin32OLE < Test::Unit::TestCase
153    include TestCaseForDict
154    def setup
155      @dict1 = WIN32OLE.new('Scripting.Dictionary')
156      @dict2 = WIN32OLE.new('Scripting.Dictionary')
157    end
158    def test_s_new
159      assert_instance_of(WIN32OLE, @dict1)
160      assert_instance_of(WIN32OLE, @dict2)
161    end
162
163    def test_s_new_exc
164      assert_raise(TypeError) {
165        WIN32OLE.new(1)
166      }
167      assert_raise(TypeError) {
168        WIN32OLE.new("Scripting.Dictionary", 1)
169      }
170    end
171
172    def test_s_new_DCOM
173      rshell = WIN32OLE.new("Shell.Application")
174      assert_instance_of(WIN32OLE, rshell)
175    end
176
177    def test_s_new_from_clsid
178      shell = WIN32OLE.new("{13709620-C279-11CE-A49E-444553540000}")
179      assert_instance_of(WIN32OLE, shell)
180      exc = assert_raise(WIN32OLERuntimeError) {
181        WIN32OLE.new("{000}")
182      }
183      assert_match(/unknown OLE server: `\{000\}'/, exc.message) #`
184    end
185
186    def test_s_connect
187      obj = WIN32OLE.connect("winmgmts:")
188      assert_instance_of(WIN32OLE, obj)
189    end
190
191    def test_s_connect_exc
192      assert_raise(TypeError) {
193        WIN32OLE.connect(1)
194      }
195    end
196
197    def test_invoke_accept_symbol_hash_key
198      fso = WIN32OLE.new('Scripting.FileSystemObject')
199      afolder = fso.getFolder(".")
200      bfolder = fso.getFolder({"FolderPath" => "."})
201      cfolder = fso.getFolder({:FolderPath => "."})
202      assert_equal(afolder.path, bfolder.path)
203      assert_equal(afolder.path, cfolder.path)
204      fso = nil
205    end
206
207    def test_setproperty
208      installer = WIN32OLE.new("WindowsInstaller.Installer")
209      record = installer.CreateRecord(2)
210      # this is the way to set property with argument in Win32OLE.
211      record.setproperty( "StringData", 1, 'dddd')
212      assert_equal('dddd', record.StringData(1))
213    end
214
215    def test_ole_type
216      fso = WIN32OLE.new('Scripting.FileSystemObject')
217      tobj = fso.ole_type
218      assert_match(/^IFileSystem/, tobj.name)
219    end
220
221    def test_ole_obj_help
222      fso = WIN32OLE.new('Scripting.FileSystemObject')
223      tobj = fso.ole_obj_help
224      assert_match(/^IFileSystem/, tobj.name)
225    end
226
227
228    def test_invoke_hash_key_non_str_sym
229      fso = WIN32OLE.new('Scripting.FileSystemObject')
230      begin
231        bfolder = fso.getFolder({1 => "."})
232        assert(false)
233      rescue TypeError
234        assert(true)
235      end
236      fso = nil
237    end
238
239    def test_get_win32ole_object
240      shell = WIN32OLE.new('Shell.Application')
241      folder = shell.nameSpace(0)
242      assert_instance_of(WIN32OLE, folder)
243    end
244
245    def test_invoke_accept_multi_hash_key
246      shell = WIN32OLE.new('Shell.Application')
247      folder = shell.nameSpace(0)
248      item = folder.items.item(0)
249      name = folder.getDetailsOf(item, 0)
250      assert_equal(item.name, name)
251      name = folder.getDetailsOf({:vItem => item, :iColumn => 0})
252      assert_equal(item.name, name)
253      name = folder.getDetailsOf({"vItem" => item, :iColumn => 0})
254      assert_equal(item.name, name)
255    end
256
257    def test_ole_invoke_with_named_arg_last
258      shell = WIN32OLE.new('Shell.Application')
259      folder = shell.nameSpace(0)
260      item = folder.items.item(0)
261      name = folder.getDetailsOf(item, {:iColumn => 0})
262      assert_equal(item.name, name)
263    end
264
265    def test__invoke
266      shell=WIN32OLE.new('Shell.Application')
267      assert_equal(shell.NameSpace(0).title, shell._invoke(0x60020002, [0], [WIN32OLE::VARIANT::VT_VARIANT]).title)
268    end
269
270    def test_ole_query_interface
271      shell=WIN32OLE.new('Shell.Application')
272      assert_raise(ArgumentError) {
273        shell2 = shell.ole_query_interface
274      }
275      shell2 = shell.ole_query_interface('{A4C6892C-3BA9-11D2-9DEA-00C04FB16162}')
276      assert_instance_of(WIN32OLE, shell2)
277    end
278
279    def test_ole_respond_to
280      fso = WIN32OLE.new('Scripting.FileSystemObject')
281      assert(fso.ole_respond_to?('getFolder'))
282      assert(fso.ole_respond_to?('GETFOLDER'))
283      assert(fso.ole_respond_to?(:getFolder))
284      assert(!fso.ole_respond_to?('XXXXX'))
285      assert_raise(TypeError) {
286        assert_raise(fso.ole_respond_to?(1))
287      }
288    end
289
290    def test_invoke
291      fso = WIN32OLE.new('Scripting.FileSystemObject')
292      assert(fso.invoke(:getFolder, "."))
293      assert(fso.invoke('getFolder', "."))
294    end
295
296    def test_s_const_load
297      assert(!defined?(CONST1::SsfWINDOWS))
298      shell=WIN32OLE.new('Shell.Application')
299      WIN32OLE.const_load(shell, CONST1)
300      assert_equal(36, CONST1::SsfWINDOWS)
301
302      assert(!defined?(CONST2::SsfWINDOWS))
303      WIN32OLE.const_load("Microsoft Shell Controls And Automation", CONST2)
304      assert_equal(36, CONST2::SsfWINDOWS)
305    end
306
307    def test_s_create_guid
308      guid = WIN32OLE.create_guid
309      assert_match(/^\{[A-Z0-9]{8}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{12}/,
310                   guid)
311    end
312
313    #
314    # WIN32OLE.codepage is initialized according to Encoding.default_external.
315    #
316    # def test_s_codepage
317    #   assert_equal(WIN32OLE::CP_ACP, WIN32OLE.codepage)
318    # end
319
320    def test_s_codepage_set
321      cp = WIN32OLE.codepage
322      WIN32OLE.codepage = WIN32OLE::CP_UTF8
323      assert_equal(WIN32OLE::CP_UTF8, WIN32OLE.codepage)
324      WIN32OLE.codepage = cp
325    end
326
327    def test_s_codepage_changed
328      cp = WIN32OLE.codepage
329      fso = WIN32OLE.new("Scripting.FileSystemObject")
330      fname = fso.getTempName
331      begin
332        obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
333        WIN32OLE.codepage = WIN32OLE::CP_UTF8
334        assert_equal("\xE3\x81\x82".force_encoding("CP65001"), obj.value)
335
336        begin
337          WIN32OLE.codepage = 932 # Windows-31J
338        rescue WIN32OLERuntimeError
339        end
340        if (WIN32OLE.codepage == 932)
341          assert_equal("\x82\xA0".force_encoding("CP932"), obj.value)
342        end
343
344        begin
345          WIN32OLE.codepage = 20932 # MS EUC-JP
346        rescue WIN32OLERuntimeError
347        end
348        if (WIN32OLE.codepage == 20932)
349          assert_equal("\xA4\xA2".force_encoding("CP20932"), obj.value)
350        end
351
352        WIN32OLE.codepage = cp
353        file = fso.opentextfile(fname, 2, true)
354        test_str = [0x3042].pack("U*").encode("UTF-16LE")
355        begin
356          file.write test_str.force_encoding("UTF-16")
357        ensure
358          file.close
359        end
360        str = ""
361        open(fname, "r:ascii-8bit") {|ifs|
362          str = ifs.read
363        }
364        assert_equal(test_str.force_encoding("ascii-8bit"), str)
365
366        # This test fail if codepage 20932 (euc) is not installed.
367        begin
368          WIN32OLE.codepage = 20932
369        rescue WIN32OLERuntimeError
370        end
371        if (WIN32OLE.codepage == 20932)
372          WIN32OLE.codepage = cp
373          file = fso.opentextfile(fname, 2, true)
374          begin
375            file.write [164, 162].pack("c*").force_encoding("UTF-16")
376          ensure
377            file.close
378          end
379          open(fname, "r:ascii-8bit") {|ifs|
380            str = ifs.read
381          }
382          assert_equal("\244\242", str)
383        end
384
385      ensure
386        WIN32OLE.codepage = cp
387        if (File.exist?(fname))
388          File.unlink(fname)
389        end
390      end
391    end
392
393    def test_cp51932
394      cp = WIN32OLE.codepage
395      begin
396        obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
397        begin
398          WIN32OLE.codepage = 51932
399        rescue
400        end
401        if WIN32OLE.codepage == 51932
402          assert_equal("\xA4\xA2".force_encoding("CP51932"), obj.value)
403        end
404      ensure
405        WIN32OLE.codepage = cp
406      end
407    end
408
409    def test_s_locale
410      assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
411    end
412
413    def test_s_locale_set
414      begin
415        begin
416          WIN32OLE.locale = 1041
417        rescue WIN32OLERuntimeError
418          STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_set is skipped(Japanese locale is not installed)")
419          return
420        end
421        assert_equal(1041, WIN32OLE.locale)
422        WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
423        assert_raise(WIN32OLERuntimeError) {
424          WIN32OLE.locale = 111
425        }
426        assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
427      ensure
428        WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
429      end
430    end
431
432    def test_s_locale_change
433      begin
434        begin
435          WIN32OLE.locale = 0x0411
436        rescue WIN32OLERuntimeError
437        end
438        if WIN32OLE.locale == 0x0411
439          obj = WIN32OLE_VARIANT.new("\\100,000", WIN32OLE::VARIANT::VT_CY)
440          assert_equal("100000", obj.value)
441          assert_raise(WIN32OLERuntimeError) {
442            obj = WIN32OLE_VARIANT.new("$100.000", WIN32OLE::VARIANT::VT_CY)
443          }
444        else
445          STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(Japanese locale is not installed)")
446        end
447
448        begin
449          WIN32OLE.locale = 1033
450        rescue WIN32OLERuntimeError
451        end
452        if WIN32OLE.locale == 1033
453          obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
454          assert_equal("100000", obj.value)
455        else
456          STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(US English locale is not installed)")
457        end
458      ensure
459        WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
460      end
461    end
462
463    def test_const_CP_ACP
464      assert_equal(0, WIN32OLE::CP_ACP)
465    end
466
467    def test_const_CP_OEMCP
468      assert_equal(1, WIN32OLE::CP_OEMCP)
469    end
470
471    def test_const_CP_MACCP
472      assert_equal(2, WIN32OLE::CP_MACCP)
473    end
474
475    def test_const_CP_THREAD_ACP
476      assert_equal(3, WIN32OLE::CP_THREAD_ACP)
477    end
478
479    def test_const_CP_SYMBOL
480      assert_equal(42, WIN32OLE::CP_SYMBOL)
481    end
482
483    def test_const_CP_UTF7
484      assert_equal(65000, WIN32OLE::CP_UTF7)
485    end
486
487    def test_const_CP_UTF8
488      assert_equal(65001, WIN32OLE::CP_UTF8)
489    end
490
491    def test_const_LOCALE_SYSTEM_DEFAULT
492      assert_equal(0x0800, WIN32OLE::LOCALE_SYSTEM_DEFAULT);
493    end
494
495    def test_const_LOCALE_USER_DEFAULT
496      assert_equal(0x0400, WIN32OLE::LOCALE_USER_DEFAULT);
497    end
498  end
499
500  # test of subclass of WIN32OLE
501  class MyDict < WIN32OLE
502    def MyDict.new
503      super('Scripting.Dictionary')
504    end
505  end
506  class TestMyDict < Test::Unit::TestCase
507    include TestCaseForDict
508    def setup
509      @dict1 = MyDict.new
510      @dict2 = MyDict.new
511    end
512    def test_s_new
513      assert_instance_of(MyDict, @dict1)
514      assert_instance_of(MyDict, @dict2)
515    end
516  end
517end
518