require 'minitest/autorun'

require 'rubygems'
#gem 'libxml-ruby'

require 'cfpropertylist'
require 'reference'

class TestDictionary < Minitest::Test
  include Reference

  def test_read_dictionary
    assert_equal({ "key" => "value" }, parsed_xml('dictionary'))
    assert_equal({ "key" => "value" }, parsed_binary('dictionary'))
  end

  def test_write_dictionary
    plist = CFPropertyList::List.new
    plist.value = CFPropertyList.guess({ "key" => "value" })
    assert_equal raw_xml('dictionary'), plist.to_str(CFPropertyList::List::FORMAT_XML, :formatted => false)
    assert_equal raw_binary('dictionary'), plist.to_str(CFPropertyList::List::FORMAT_BINARY)
  end

  def test_many_keys
    # Since Dictionaries/Hashes are typically unordered, it's probably
    # unreasonable to expect that whatever is generated by CFPropertyList will
    # match the order of keys from Foundation. It's probably even possible
    # that the same NSDictionary from Foundation might produce a different
    # serialized property list, depending on the order that the objects
    # were added to the dictionary.
    #
    # So instead, a different approach for this test: given a Hash, generating
    # a plist (both XML and binary) and then reading it back in should result
    # in the same Hash.

    hash = {
      'string' => 'abcd',
      'integer' => 1,
      'real' => 1.5,
      'date' => Time.local(2000, 1, 1, 12, 0, 0, 0)
    }

    plist = CFPropertyList::List.new
    plist.value = CFPropertyList.guess(hash)

    serialized = plist.to_str(CFPropertyList::List::FORMAT_XML, :formatted => true)
    reparsed = CFPropertyList::List.new(:data => serialized)
    assert_equal hash, CFPropertyList.native_types(reparsed.value)

    serialized = plist.to_str(CFPropertyList::List::FORMAT_BINARY)
    File.new('test.plist', 'w').write(serialized)
    reparsed = CFPropertyList::List.new(:data => serialized)
    assert_equal hash, CFPropertyList.native_types(reparsed.value)
  end


  def test_empty_key_with_rexml
    orig_parsers = CFPropertyList::List.parsers
    require 'cfpropertylist/rbREXMLParser'
    CFPropertyList::List.parsers = [CFPropertyList::Binary, CFPropertyList::ReXMLParser]
    example_data = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key></key>
    <string>test</string>
  </dict>
</plist>
XML

    lst = CFPropertyList::List.new
    lst.load_str(example_data)

    assert_equal "", lst.value.value.keys.first

  ensure
    CFPropertyList::List.parsers = orig_parsers
  end
end
