xbel 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.2.4
@@ -35,6 +35,10 @@ module Nokogiri::Decorators::XBEL
35
35
  end
36
36
  attr_reader :info
37
37
 
38
+ def attributes=(attributes)
39
+ attributes.each { |key, value| send "#{ key }=", value }
40
+ end
41
+
38
42
  # Returns description of node.
39
43
  def desc
40
44
  if node = at('./desc') then node.content end
@@ -77,7 +81,12 @@ module Nokogiri::Decorators::XBEL
77
81
  end
78
82
  # Sets addition date.
79
83
  def added=(value)
80
- set_attribute 'added', value.to_s
84
+ set_attribute 'added', case value
85
+ when Time; value.strftime '%Y-%m-%d'
86
+ when String; value
87
+ else
88
+ raise ArgumentError
89
+ end
81
90
  end
82
91
 
83
92
  # Returns nil.
@@ -34,31 +34,31 @@ module Nokogiri::Decorators::XBEL
34
34
  super
35
35
  end
36
36
 
37
- def build(type, attributes = {}, &block)
38
- child = Nokogiri::XML::Node.new(type.to_s, document)
39
- assign_to child, attributes, &block
37
+ def build(type, attributes = {})
38
+ node = Nokogiri::XML::Node.new(type.to_s, document)
39
+ node.attributes = attributes
40
40
 
41
- add_child child
41
+ yield node if block_given?
42
+
43
+ node
42
44
  end
43
45
 
44
46
  # Builds a bookmark with given attributes and add it.
45
- def build_bookmark(title, href, attributes = {}, &block)
46
- build :bookmark,
47
- attributes.merge(:title => title, :href => href),
48
- &block
47
+ def add_bookmark(title, href, attributes = {}, &block)
48
+ attributes = attributes.merge :title => title, :href => href
49
+ add_child build(:bookmark, attributes, &block)
49
50
  end
50
51
  # Builds a folder with given attributes and add it.
51
- def build_folder(title, attributes = {}, &block)
52
- build :folder,
53
- attributes.merge(:title => title),
54
- &block
52
+ def add_folder(title, attributes = {}, &block)
53
+ attributes = attributes.merge :title => title
54
+ add_child build(:folder, attributes, &block)
55
55
  end
56
56
  # Builds an alias with given attributes and add it.
57
- def build_alias(ref)
58
- child = Nokogiri::XML::Node.new('alias', document)
59
- child.ref = (Entry === ref) ? ref.id : ref.to_s
57
+ def add_alias(ref)
58
+ node = Nokogiri::XML::Node.new 'alias', document
59
+ node.ref = (Entry === ref) ? ref.id : ref.to_s
60
60
 
61
- add_child child
61
+ add_child node
62
62
  end
63
63
  # Builds a saperator with given attributes and add it.
64
64
  def add_separator
@@ -67,18 +67,21 @@ module Nokogiri::Decorators::XBEL
67
67
 
68
68
  protected
69
69
 
70
- def assign_to(node, attributes) #:nodoc:
71
- attributes[:id] ||= "#{ id }." << xpath('./bookmark | ./folder').
70
+ def generate_id
71
+ "#{ id }#{ document.div_id_er }" << xpath('./bookmark | ./folder').
72
72
  inject(0) { |next_id, child|
73
73
  succ_num_id = child.id[/(\d+)$/, 1].to_i.succ
74
74
  succ_num_id > next_id ? succ_num_id : next_id
75
75
  }.to_s
76
+ end
76
77
 
77
- attributes.each do |key, value|
78
- node.send "#{ key }=", value
78
+ def add_child(node)
79
+ if Entry === node
80
+ node.id ||= generate_id
81
+ node.added = Time.now
79
82
  end
80
83
 
81
- yield node if block_given?
84
+ super
82
85
  end
83
86
 
84
87
  end
data/lib/xbel.rb CHANGED
@@ -5,11 +5,22 @@ require 'nokogiri/decorators/xbel'
5
5
 
6
6
  class XBEL < Nokogiri::XML::Document
7
7
  extend Forwardable
8
- def_delegators :root, :title, :title=, :desc, :desc=
8
+ def_delegators :root,
9
+ :title, :title=,
10
+ :desc, :desc=,
11
+ :id, :id=
12
+
13
+ attr_accessor :div_id_er
14
+
15
+ TEMPLATE = %Q'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"><xbel version="1.0" id="0"></xbel>'
16
+ DIV_ID_ER = '_'
9
17
 
10
18
  # Returns an instance of XBEL.
11
- def self.new(major = 1, minor = 0)
12
- parse %Q'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"><xbel version="%i.%i"></xbel>' % [major, minor]
19
+ def self.new(attributes = {})
20
+ xbel = parse TEMPLATE
21
+ xbel.attributes = attributes
22
+
23
+ xbel
13
24
  end
14
25
 
15
26
  # Reads file at <tt>path</tt> into <tt>parse</tt>.
@@ -24,6 +35,8 @@ class XBEL < Nokogiri::XML::Document
24
35
  super
25
36
  decorators(Nokogiri::XML::Node) << Nokogiri::Decorators::XBEL
26
37
  decorate!
38
+
39
+ @div_id_er = DIV_ID_ER
27
40
  end
28
41
 
29
42
  # Returns node with given <tt>id</tt>.
@@ -31,6 +44,13 @@ class XBEL < Nokogiri::XML::Document
31
44
  root.at("//*[@id='#{ id }']")
32
45
  end
33
46
 
47
+ def attributes=(attributes)
48
+ version = attributes.delete(:version) and self.version = version
49
+ div_id_er = attributes.delete(:div_id_er) and self.div_id_er = div_id_er
50
+
51
+ root.attributes = attributes
52
+ end
53
+
34
54
  # Returns an array of version numbers.
35
55
  def version
36
56
  root.attribute('version').value.split('.').map { |n| n.to_i }
data/test/test_xbel.rb CHANGED
@@ -1,142 +1,172 @@
1
1
  require 'helper'
2
2
 
3
- context 'New XBEL' do
4
-
5
- asserts 'version' do
6
- XBEL.new.version
7
- end.equals [1, 0]
8
- asserts 'user defined version' do
9
- XBEL.new(2, 2).version
10
- end.equals [2, 2]
11
- asserts 'set version' do
12
- xbel = XBEL.new
13
- xbel.version = 1, 1
14
-
15
- xbel.version
16
- end.equals [1, 1]
17
- should 'be empty' do
18
- XBEL.new.root.content.empty?
19
- end
20
-
21
- end
22
-
23
3
  context 'XBEL' do
24
-
25
- setup do
26
- root = Pathname.new File.dirname(__FILE__)
27
- XBEL.open root.join('wikipedia.xbel')
4
+ setup { XBEL }
5
+
6
+ context 'build with defaults' do
7
+ setup { topic.new }
8
+
9
+ asserts 'version' do
10
+ topic.version
11
+ end.equals [1, 0]
12
+ asserts 'version set' do
13
+ topic.version = 1, 1
14
+ topic.version
15
+ end.equals [1, 1]
16
+ should 'be empty' do
17
+ topic.root.content.empty?
18
+ end
19
+ should 'have an id divider' do
20
+ String === topic.div_id_er and
21
+ topic.div_id_er.length > 0
22
+ end
23
+ end
24
+ context 'built with attributes' do
25
+ setup { topic.new :version => [2, 2], :div_id_er => '/', :id => 'custom' }
26
+
27
+ asserts 'user defined version' do
28
+ topic.version
29
+ end.equals [2, 2]
30
+ asserts 'div_id_er' do
31
+ topic.div_id_er
32
+ end.equals '/'
33
+ asserts 'id' do
34
+ topic.id
35
+ end.equals 'custom'
36
+
37
+ asserts 'id of added folder' do
38
+ topic.root.add_folder('foo').id
39
+ end.equals 'custom/0'
28
40
  end
29
41
 
30
- asserts('version') { topic.version }.equals [1, 0]
42
+ context 'loaded from wikipedia.xbel' do
43
+ setup do
44
+ root = Pathname.new File.dirname(__FILE__)
45
+ topic.open root.join('wikipedia.xbel')
46
+ end
31
47
 
32
- asserts('title') { topic.title }.equals 'Lesezeichen!'
33
- should('delegate title accessor to root') do
34
- topic.title = 'Bookmarks!'
48
+ asserts('version') { topic.version }.equals [1, 0]
35
49
 
36
- topic.title == topic.root.title and
37
- topic.title == 'Bookmarks!'
38
- end
50
+ asserts('title') { topic.title }.equals 'Lesezeichen!'
51
+ should('delegate title accessor to root') do
52
+ topic.title = 'Bookmarks!'
39
53
 
40
- context 'Alias' do
41
- setup { topic.root.aliases.first }
42
- should('be an alias') { topic.alias? }
43
-
44
- should('have a reference') do
45
- topic.ref and
46
- topic.ref == topic.reference
54
+ topic.title == topic.root.title and
55
+ topic.title == 'Bookmarks!'
47
56
  end
48
- end
49
57
 
50
- context 'Folder' do
51
- setup { topic[:f0] }
52
- should('be a folder') { topic.folder? }
58
+ context 'Alias' do
59
+ setup { topic.root.aliases.first }
60
+ should('be an alias') { topic.alias? }
53
61
 
54
- asserts('title') { topic.title }.equals 'Wiki'
55
- asserts('entries names') do
56
- topic.entries.map { |e| e.name }.uniq.sort
57
- end.equals %w[ alias bookmark folder separator ]
58
- should('return bookmarks') do
59
- not topic.bookmarks.any? { |b| b.name != 'bookmark' }
60
- end
61
- should('return aliases') do
62
- not topic.aliases.any? { |b| b.name != 'alias' }
62
+ should('have a reference') do
63
+ topic.ref and
64
+ topic.ref == topic.reference
65
+ end
63
66
  end
64
- should('return folders') do
65
- not topic.folders.any? { |b| b.name != 'folder' }
67
+
68
+ context 'root' do
69
+ setup { topic.root }
70
+ context 'new Bookmark' do
71
+ setup do
72
+ topic.add_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
73
+ :description => 'Ruby API for XBEL based on Nokogiri.'
74
+ end
75
+ asserts('next id') { topic.id }.equals 'test_2'
76
+ end
66
77
  end
67
78
 
68
- context 'Bookmark' do
69
- setup { topic.bookmarks.first }
70
- should('be a bookmark') { topic.bookmark? }
79
+ context 'Folder' do
80
+ setup { topic[:test_1] }
81
+ should('be a folder') { topic.folder? }
71
82
 
72
- asserts('modified') { topic.modified }.kind_of Date
83
+ asserts('title') { topic.title }.equals 'Wiki'
84
+ asserts('entries names') do
85
+ topic.entries.map { |e| e.name }.uniq.sort
86
+ end.equals %w[ alias bookmark folder separator ]
87
+ should('return bookmarks') do
88
+ not topic.bookmarks.any? { |b| b.name != 'bookmark' }
89
+ end
90
+ should('return aliases') do
91
+ not topic.aliases.any? { |b| b.name != 'alias' }
92
+ end
93
+ should('return folders') do
94
+ not topic.folders.any? { |b| b.name != 'folder' }
95
+ end
73
96
 
74
- asserts('visited') { topic.visited }.kind_of Date
75
- asserts('visit') do
76
- topic.visit
77
- topic.visited
78
- end.equals Date.today
79
- end
80
- context 'new Bookmark' do
81
- setup do
82
- topic.build_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
83
- :description => 'Ruby API for XBEL based on Nokogiri.'
97
+ context 'Bookmark' do
98
+ setup { topic.bookmarks.first }
99
+ should('be a bookmark') { topic.bookmark? }
100
+
101
+ asserts('modified') { topic.modified }.kind_of Date
102
+
103
+ asserts('visited') { topic.visited }.kind_of Date
104
+ asserts('visit') do
105
+ topic.visit
106
+ topic.visited
107
+ end.equals Date.today
108
+ end
109
+ context 'new Bookmark' do
110
+ setup do
111
+ topic.add_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
112
+ :description => 'Ruby API for XBEL based on Nokogiri.'
113
+ end
114
+ should('be a bookmark') { topic.bookmark? }
115
+
116
+ asserts('added') { topic.added }.equals Date.today
117
+ asserts('title') { topic.title }.equals 'boof\'s xbel'
118
+ asserts('next id') { topic.id }.equals 'test_1_4'
119
+ asserts('href') { topic.href }.
120
+ equals 'http://www.github.com/boof/xbel'
121
+ asserts('description') { topic.description }.
122
+ equals 'Ruby API for XBEL based on Nokogiri.'
84
123
  end
85
- should('be a bookmark') { topic.bookmark? }
86
124
 
87
- asserts('added') { topic.added }.equals Date.today
88
- asserts('title') { topic.title }.equals 'boof\'s xbel'
89
- asserts('next id') { topic.id }.equals 'f0.2'
90
- asserts('href') { topic.href }.
91
- equals 'http://www.github.com/boof/xbel'
92
- asserts('description') { topic.description }.
93
- equals 'Ruby API for XBEL based on Nokogiri.'
94
- end
125
+ context 'new Folder' do
126
+ setup { topic.add_folder 'sub', :desc => 'desc' }
127
+ should('be a folder') { topic.folder? }
95
128
 
96
- context 'new Folder' do
97
- setup { topic.build_folder 'sub', :desc => 'desc' }
98
- should('be a folder') { topic.folder? }
129
+ asserts('added') { topic.added }.equals Date.today
130
+ asserts('title') { topic.title }.equals 'sub'
131
+ asserts('next id') { topic.id }.equals 'test_1_4'
132
+ asserts('desc') { topic.desc }.equals 'desc'
133
+ end
99
134
 
100
- asserts('added') { topic.added }.equals Date.today
101
- asserts('title') { topic.title }.equals 'sub'
102
- asserts('next id') { topic.id }.equals 'f0.2'
103
- asserts('desc') { topic.desc }.equals 'desc'
104
- end
135
+ context 'new Alias' do
136
+ setup { topic.add_alias topic }
137
+ should('be an alias') { topic.alias? }
105
138
 
106
- context 'new Alias' do
107
- setup { topic.build_alias topic }
108
- should('be an alias') { topic.alias? }
139
+ should('reference its folder') { topic.entry == topic.parent }
140
+ should('set reference by entry') do
141
+ topic.entry = topic.document[:test_1_3]
142
+ topic.ref == 'test_1_3'
143
+ end
144
+ end
109
145
 
110
- should('reference its folder') { topic.entry == topic.parent }
111
- should('set reference by entry') do
112
- topic.entry = topic.document[:b1]
113
- topic.ref == 'b1'
146
+ context 'Separator' do
147
+ setup { topic.entries.find { |e| e.name == 'separator' } }
148
+ asserts('to_s') { topic.to_s }.equals ' '
114
149
  end
115
- end
116
150
 
117
- context 'Separator' do
118
- setup { topic.entries.find { |e| e.name == 'separator' } }
119
- asserts('to_s') { topic.to_s }.equals ' '
120
151
  end
121
152
 
122
- end
153
+ context 'Bookmark b0' do
154
+ setup { topic[:test_1_1] }
155
+ should('be a bookmark') { topic.bookmark? }
123
156
 
124
- context 'Bookmark b0' do
125
- setup { topic[:b0] }
126
- should('be a bookmark') { topic.bookmark? }
127
-
128
- context 'Info' do
129
- setup { topic.info }
130
- should('be a hash') { Hash === topic }
157
+ context 'Info' do
158
+ setup { topic.info }
159
+ should('be a hash') { Hash === topic }
131
160
 
132
- context 'metadata for xbel' do
133
- setup { topic[:xbel] if topic }
134
- should('be a node') { Nokogiri::XML::Node === topic }
161
+ context 'metadata for xbel' do
162
+ setup { topic[:xbel] if topic }
163
+ should('be a node') { Nokogiri::XML::Node === topic }
135
164
 
136
- should('be have an alias') { not topic.at('./alias').nil? }
165
+ should('be have an alias') { not topic.at('./alias').nil? }
166
+ end
137
167
  end
138
- end
139
168
 
169
+ end
140
170
  end
141
171
 
142
172
  end
data/test/wikipedia.xbel CHANGED
@@ -2,27 +2,27 @@
2
2
  <!DOCTYPE xbel
3
3
  PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
4
4
  "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
5
- <xbel version="1.0">
5
+ <xbel version="1.0" id="test">
6
6
  <title>Lesezeichen!</title>
7
7
  <desc>Lernen von XBEL am Beispiel von zwei Lesezeichen und einer Verknüpfung</desc>
8
- <folder id="f0" added="2007-11-10">
8
+ <folder id="test_1" added="2007-11-10">
9
9
  <title>Wiki</title>
10
10
  <desc>Webseiten von Autoren-Gemeinschaften</desc>
11
- <bookmark href="http://wikimediafoundation.org/" id="b0" added="2007-11-11" modified="2007-11-14" visited="2007-11-14">
11
+ <bookmark href="http://wikimediafoundation.org/" id="test_1_1" added="2007-11-11" modified="2007-11-14" visited="2007-11-14">
12
12
  <info>
13
13
  <metadata owner="xbel">
14
- <alias ref="f0" />
14
+ <alias ref="test_1" />
15
15
  </metadata>
16
16
  </info>
17
17
  <title>Wikimedia Foundation</title>
18
18
  </bookmark>
19
- <alias ref="f0-1" />
19
+ <alias ref="test_1_1" />
20
20
  <separator />
21
- <bookmark href="http://de.wikipedia.org/" id="b1" added="2007-11-11" modified="2007-11-14" visited="2007-12-27">
21
+ <bookmark href="http://de.wikipedia.org/" id="test_1_2" added="2007-11-11" modified="2007-11-14" visited="2007-12-27">
22
22
  <title>Wikipedia</title>
23
23
  </bookmark>
24
- <folder id="f0-1"></folder>
24
+ <folder id="test_1_3"></folder>
25
25
  </folder>
26
26
  <separator />
27
- <alias ref="b1" />
27
+ <alias ref="test_1_2" />
28
28
  </xbel>
data/xbel.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{xbel}
8
- s.version = "0.2.3"
8
+ s.version = "0.2.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Florian A\303\237mann"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xbel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Florian A\xC3\x9Fmann"