gearbox 0.1.0 → 0.1.10

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 (43) hide show
  1. data/Gemfile +5 -3
  2. data/Rakefile +1 -0
  3. data/VERSION +1 -1
  4. data/bin/gearbox +9 -0
  5. data/gearbox.gemspec +134 -0
  6. data/lib/gearbox.rb +124 -5
  7. data/lib/gearbox/attribute.rb +128 -0
  8. data/lib/gearbox/mixins/active_model_implementation.rb +27 -0
  9. data/lib/gearbox/mixins/resource.rb +20 -4
  10. data/lib/gearbox/mixins/semantic_accessors.rb +128 -89
  11. data/lib/gearbox/mixins/subject_methods.rb +88 -0
  12. data/lib/gearbox/rdf_collection.rb +22 -8
  13. data/lib/gearbox/types.rb +9 -8
  14. data/lib/gearbox/vocabulary.rb +149 -0
  15. data/lib/pry_utilities.rb +71 -0
  16. data/scratch/4s.rb +335 -0
  17. data/scratch/DEVELOPMENT_NOTES.md +85 -0
  18. data/scratch/actionable.md +34 -0
  19. data/scratch/ccrdf.html-rdfa.nq +100 -0
  20. data/scratch/foo.rb +17 -0
  21. data/scratch/index.rdf +7932 -0
  22. data/scratch/j2.rb +10 -0
  23. data/scratch/junk.rb +16 -0
  24. data/scratch/out.rb +67 -0
  25. data/spec/gearbox/attribute_spec.rb +455 -0
  26. data/spec/gearbox/mixins/active_model_implementation_spec.rb +18 -0
  27. data/spec/gearbox/mixins/ad_hoc_properties_spec.rb +44 -44
  28. data/spec/gearbox/mixins/resource_spec.rb +47 -8
  29. data/spec/gearbox/mixins/semantic_accessors_spec.rb +72 -43
  30. data/spec/gearbox/mixins/subject_methods_spec.rb +126 -0
  31. data/spec/gearbox/rdf_collection_spec.rb +28 -2
  32. data/spec/gearbox_spec.rb +6 -2
  33. data/spec/spec_helper.rb +1 -0
  34. metadata +150 -42
  35. data/Gemfile.lock +0 -138
  36. data/lib/examples/audience.rb +0 -24
  37. data/lib/examples/person.rb +0 -29
  38. data/lib/examples/reference.rb +0 -38
  39. data/lib/examples/theme.rb +0 -8
  40. data/spec/examples/audience_spec.rb +0 -28
  41. data/spec/examples/person_spec.rb +0 -45
  42. data/spec/examples/reference_spec.rb +0 -43
  43. data/spec/examples/theme_spec.rb +0 -137
@@ -0,0 +1,10 @@
1
+ class A
2
+ def go
3
+ :go
4
+ end
5
+
6
+ def hey
7
+ binding.pry
8
+ :hey
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ require 'pry'
2
+
3
+ class A
4
+ def hello() puts "hello world!" end
5
+ end
6
+
7
+ a = A.new
8
+
9
+ # set x to 10
10
+ x = 10
11
+
12
+ # start a REPL session
13
+ binding.pry
14
+
15
+ # program resumes here (after pry session)
16
+ puts "program resumes here. Value of x is: #{x}."
@@ -0,0 +1,67 @@
1
+ require 'pry'
2
+ # print "This is a test"
3
+ # STDOUT.flush
4
+ # sleep 1
5
+ # print "\r"
6
+ # STDOUT.flush
7
+ # print "this is another test\n"
8
+ # STDOUT.flush
9
+ # puts "Done!"
10
+
11
+
12
+ def terminal_width
13
+ @terminal_width ||= (ENV["COLUMNS"] || 80).to_i
14
+ end
15
+
16
+ def terminal_height
17
+ @terminal_height ||= (ENV["COLUMNS"] || 20).to_i
18
+ end
19
+
20
+ def print_line(line, opts={})
21
+ padding = opts.fetch(:padding, terminal_width)
22
+ out = opts.fetch(:out, STDOUT)
23
+ print "\r" unless opts[:skip_r]
24
+ print line.strip.ljust(padding)
25
+ out.flush
26
+ end
27
+
28
+ def lines
29
+ @lines ||= {}
30
+ end
31
+
32
+ def sorted_lines
33
+ output = Hash.new("")
34
+ lines.sort {|(key_a, value_a), (key_b, value_b)| key_a <=> key_b}.each do |(key, value)|
35
+ output[key] = value
36
+ end
37
+ output
38
+ end
39
+
40
+ def print_on_line(n, line, opts={})
41
+ hash = sorted_lines
42
+ last, value = sorted_lines.max
43
+ count = last - n
44
+ out = opts.fetch(:out, STDOUT)
45
+
46
+ count.times {out.print "\r"; out.flush} if count > 0
47
+
48
+ (n..last).each do |i|
49
+ lines[i] = line if n == i
50
+ print_line(hash[i], opts.merge(:skip_r => true))
51
+ out.print("\n")
52
+ end
53
+
54
+ end
55
+
56
+ lines[2] = "two"
57
+ lines[1] = "one"
58
+ lines[3] = "three"
59
+ lines[4] = "four"
60
+
61
+ print_on_line(1, "1")
62
+ print_on_line(2, "2")
63
+
64
+ # if __FILE__ == $0
65
+ # puts "sdfasdfasdf", ENV["COLUMNS"].nil?, $stdout.methods.sort - Object.methods
66
+ # end
67
+
@@ -0,0 +1,455 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Gearbox
4
+
5
+ describe Attribute do
6
+
7
+ subject { Attribute.new }
8
+
9
+ it "has an accessor for predicate" do
10
+ subject.predicate = :predicate
11
+ subject.predicate.must_equal :predicate
12
+ end
13
+
14
+ it "can load with :predicate or 'predicate'" do
15
+ subject = Attribute.new(:predicate => :predicate)
16
+ subject.predicate.must_equal :predicate
17
+ subject = Attribute.new('predicate' => :predicate)
18
+ subject.predicate.must_equal :predicate
19
+ end
20
+
21
+ it "has an accessor for reverse" do
22
+ subject.reverse = :reverse
23
+ subject.reverse.must_equal :reverse
24
+ end
25
+
26
+ it "can load with :reverse or 'reverse'" do
27
+ subject = Attribute.new(:reverse => :reverse)
28
+ subject.reverse.must_equal :reverse
29
+ subject = Attribute.new('reverse' => :reverse)
30
+ subject.reverse.must_equal :reverse
31
+ end
32
+
33
+ it "defaults reverse to false" do
34
+ subject.reverse.must_equal false
35
+ end
36
+
37
+ it "has an accessor for index" do
38
+ subject.index = :index
39
+ subject.index.must_equal :index
40
+ end
41
+
42
+ it "can load with :index or 'index'" do
43
+ subject = Attribute.new(:index => :index)
44
+ subject.index.must_equal :index
45
+ subject = Attribute.new('index' => :index)
46
+ subject.index.must_equal :index
47
+ end
48
+
49
+ it "defaults index to false" do
50
+ subject.index.must_equal false
51
+ end
52
+
53
+ it "has an accessor for name" do
54
+ subject.name = :name
55
+ subject.name.must_equal :name
56
+ end
57
+
58
+ it "can load with :name or 'name'" do
59
+ subject = Attribute.new(:name => :name)
60
+ subject.name.must_equal :name
61
+ subject = Attribute.new('name' => :name)
62
+ subject.name.must_equal :name
63
+ end
64
+
65
+ it "has an accessor for repository" do
66
+ subject.repository = :repository
67
+ subject.repository.must_equal :repository
68
+ end
69
+
70
+ it "can load with :repository or 'repository'" do
71
+ subject = Attribute.new(:repository => :repository)
72
+ subject.repository.must_equal :repository
73
+ subject = Attribute.new('repository' => :repository)
74
+ subject.repository.must_equal :repository
75
+ end
76
+
77
+ it "has an accessor for subject_decorator" do
78
+ subject.subject_decorator = :some_method
79
+ subject.subject_decorator.must_equal :some_method
80
+ end
81
+
82
+ it "can load with :subject_decorator or 'subject_decorator'" do
83
+ subject = Attribute.new(:subject_decorator => :subject_decorator)
84
+ subject.subject_decorator.must_equal :subject_decorator
85
+ subject = Attribute.new('subject_decorator' => :subject_decorator)
86
+ subject.subject_decorator.must_equal :subject_decorator
87
+ end
88
+
89
+ it "can attempt to build a subject, if the subject_decorator is set" do
90
+ def subject.some_method; "special_subject"; end
91
+ subject.subject_decorator = :some_method
92
+ subject.subject.must_equal "special_subject"
93
+ end
94
+
95
+ it "returns nil from subject if the subject_decorator is not set" do
96
+ subject.subject.must_equal nil
97
+ end
98
+
99
+ it "can load with :value or 'value'" do
100
+ subject = Attribute.new(:value => :value)
101
+ subject.to_value.must_equal :value
102
+ subject = Attribute.new('value' => :value)
103
+ subject.to_value.must_equal :value
104
+ end
105
+
106
+ it "uses to_value or get to lookup the value" do
107
+ subject = Attribute.new(:value => :value)
108
+ subject.to_value.must_equal :value
109
+ subject.get.must_equal :value
110
+ end
111
+
112
+ it "has an accessor for datatype" do
113
+ subject.datatype = :value
114
+ subject.datatype.must_equal :value
115
+ end
116
+
117
+ it "can load with :datatype or 'datatype'" do
118
+ subject = Attribute.new(:datatype => :datatype)
119
+ subject.datatype.must_equal :datatype
120
+ subject = Attribute.new('datatype' => :datatype)
121
+ subject.datatype.must_equal :datatype
122
+ end
123
+
124
+ it "has an accessor for language" do
125
+ subject.datatype = :language
126
+ subject.datatype.must_equal :language
127
+ end
128
+
129
+ it "can load with :language or 'language'" do
130
+ subject = Attribute.new(:language => :language)
131
+ subject.language.must_equal :language
132
+ subject = Attribute.new('language' => :language)
133
+ subject.language.must_equal :language
134
+ end
135
+
136
+ it "can set the value to false or nil" do
137
+ subject.set false
138
+ subject.value.must_equal false
139
+ end
140
+
141
+ describe "literal" do
142
+ describe "as prompted by Attribute instance changes" do
143
+ it "defaults the literal to no data type at all" do
144
+ value = "Basic Value"
145
+ subject.set value
146
+ subject.literal.datatype.must_equal nil
147
+ subject.literal.object.must_equal value
148
+ subject.literal.value.must_equal value
149
+ end
150
+
151
+ it "handles a boolean as expected" do
152
+ value = true
153
+ subject.set value
154
+ subject.literal.datatype.must_equal RDF::XSD.boolean
155
+ subject.literal.object.must_equal value
156
+ subject.literal.value.must_equal 'true'
157
+
158
+ value = false
159
+ subject.set value
160
+ subject.literal.datatype.must_equal RDF::XSD.boolean
161
+ subject.literal.object.must_equal value
162
+ subject.literal.value.must_equal 'false'
163
+ end
164
+
165
+ it "handles a date as expected" do
166
+ value = Time.now.to_date
167
+ subject.set value
168
+ subject.literal.datatype.must_equal RDF::XSD.date
169
+ subject.literal.object.must_equal value
170
+ subject.literal.value.must_equal value.to_s + "Z"
171
+ end
172
+
173
+ it "handles date_time as expected" do
174
+ value = Time.now.to_datetime
175
+ subject.set value
176
+ subject.literal.datatype.must_equal RDF::XSD.dateTime
177
+ subject.literal.object.must_equal value
178
+ subject.literal.value.must_equal value.to_s
179
+ end
180
+
181
+ it "handles a decimal as expected" do
182
+ value = 1.5
183
+ subject.set value
184
+ subject.datatype = RDF::XSD.decimal # Note, a plain decimal shows up as a double, rather than a decimal.
185
+ subject.literal.datatype.must_equal RDF::XSD.decimal
186
+ subject.literal.object.must_equal value
187
+ subject.literal.value.must_equal "1.5"
188
+ end
189
+
190
+ it "handles a double as expected" do
191
+ value = 1.5
192
+ subject.set value
193
+ subject.literal.datatype.must_equal RDF::XSD.double
194
+ subject.literal.object.must_equal value
195
+ subject.literal.value.must_equal "1.5"
196
+ end
197
+
198
+ it "handles time as expected" do
199
+ value = Time.now
200
+ subject.set value
201
+ subject.literal.datatype.must_equal RDF::XSD.time
202
+ subject.literal.object.must_equal value
203
+ subject.literal.value.must_equal value.strftime("%H:%M:%S%Z")
204
+ end
205
+
206
+ # Note, I'm skipping token because the underlying RDF doesn't seem to work, and I don't
207
+ # have a use case for it.
208
+ # Also, I'm skipping XML because I don't have a use case for XML yet.
209
+ end # "as prompted by Attribute instance changes"
210
+
211
+ describe "as prompted by parameter changes" do
212
+ it "defaults the literal to no data type at all" do
213
+ value = "Basic Value"
214
+ literal = subject.literal(:value => value)
215
+ literal.datatype.must_equal nil
216
+ literal.object.must_equal value
217
+ literal.value.must_equal value
218
+ end
219
+
220
+ it "handles a boolean as expected" do
221
+ value = true
222
+ literal = subject.literal(:value => value)
223
+ literal.datatype.must_equal RDF::XSD.boolean
224
+ literal.object.must_equal value
225
+ literal.value.must_equal 'true'
226
+
227
+ value = false
228
+ literal = subject.literal(:value => value)
229
+ literal.datatype.must_equal RDF::XSD.boolean
230
+ literal.object.must_equal value
231
+ literal.value.must_equal 'false'
232
+ end
233
+
234
+ it "handles a date as expected" do
235
+ value = Time.now.to_date
236
+ literal = subject.literal(:value => value)
237
+ literal.datatype.must_equal RDF::XSD.date
238
+ literal.object.must_equal value
239
+ literal.value.must_equal value.to_s + "Z"
240
+ end
241
+
242
+ it "handles date_time as expected" do
243
+ value = Time.now.to_datetime
244
+ literal = subject.literal(:value => value)
245
+ literal.datatype.must_equal RDF::XSD.dateTime
246
+ literal.object.must_equal value
247
+ literal.value.must_equal value.to_s
248
+ end
249
+
250
+ it "handles a decimal as expected" do
251
+ value = 1.5
252
+ literal = subject.literal(:value => value, :datatype => RDF::XSD.decimal)
253
+ literal.datatype.must_equal RDF::XSD.decimal
254
+ literal.object.must_equal value
255
+ literal.value.must_equal "1.5"
256
+ end
257
+
258
+ it "handles a double as expected" do
259
+ value = 1.5
260
+ literal = subject.literal(:value => value)
261
+ literal.datatype.must_equal RDF::XSD.double
262
+ literal.object.must_equal value
263
+ literal.value.must_equal "1.5"
264
+ end
265
+
266
+ it "handles time as expected" do
267
+ value = Time.now
268
+ literal = subject.literal(:value => value)
269
+ literal.datatype.must_equal RDF::XSD.time
270
+ literal.object.must_equal value
271
+ literal.value.must_equal value.strftime("%H:%M:%S%Z")
272
+ end
273
+ end # "as prompted by parameter changes"
274
+
275
+ end # literal
276
+
277
+ describe "to_rdf" do
278
+
279
+ let(:model) do
280
+ Class.new do
281
+ def subject
282
+ "http://example.com/demo/1"
283
+ end
284
+ end.new
285
+ end
286
+
287
+ subject { Attribute.new(:name => :name, :predicate => RDF::FOAF.name)}
288
+
289
+ describe "as prompted from the Attribute instance" do
290
+ it "uses the model subject" do
291
+ rdf = subject.to_rdf(model)
292
+ rdf.subject.must_equal model.subject
293
+ end
294
+
295
+ it "uses the attribute predicate" do
296
+ rdf = subject.to_rdf(model)
297
+ rdf.predicate.must_equal RDF::FOAF.name
298
+ end
299
+
300
+ it "uses the attribute value for object" do
301
+ subject.set "George"
302
+ rdf = subject.to_rdf(model)
303
+ object = rdf.object
304
+ object.to_s.must_equal "George"
305
+ object.must_be_kind_of RDF::Literal
306
+ end
307
+
308
+ it "uses the language when provided" do
309
+ subject.language = :es
310
+ subject.set("Jorge")
311
+ rdf = subject.to_rdf(model)
312
+ rdf.object.language.must_equal :es
313
+ end
314
+
315
+ it "reverses the subject and object with reverse" do
316
+ subject.reverse = true
317
+ subject.set("George")
318
+ rdf = subject.to_rdf(model)
319
+ rdf.subject.to_s.must_equal "George"
320
+ rdf.subject.must_be_kind_of RDF::Literal
321
+ rdf.predicate.must_equal RDF::FOAF.name
322
+ rdf.object.to_s.must_equal model.subject
323
+ rdf.object.must_be_kind_of RDF::URI
324
+ end
325
+
326
+ it "uses a subject_decorator for overriding the model subject" do
327
+ subject.subject_decorator = :special_subject
328
+ def subject.special_subject
329
+ "http://example.com/special_subject"
330
+ end
331
+ rdf = subject.to_rdf(model)
332
+ rdf.subject.to_s.must_equal "http://example.com/special_subject"
333
+ rdf.subject.must_be_kind_of RDF::URI
334
+ end
335
+
336
+ it "uses a subject_decorator as a lambda" do
337
+ subject.subject_decorator = lambda{"http://example.com/special_subject"}
338
+ rdf = subject.to_rdf(model)
339
+ rdf.subject.to_s.must_equal "http://example.com/special_subject"
340
+ rdf.subject.must_be_kind_of RDF::URI
341
+ end
342
+
343
+ it "uses the local subject before using the model subject, if defined" do
344
+ def subject.subject
345
+ "http://example.com/special_subject"
346
+ end
347
+ rdf = subject.to_rdf(model)
348
+ rdf.subject.to_s.must_equal "http://example.com/special_subject"
349
+ rdf.subject.must_be_kind_of RDF::URI
350
+ end
351
+ end # "as prompted from the Attribute instance"
352
+
353
+ describe "as prompted from the call parameters" do
354
+
355
+ it "can take a predicate parameter" do
356
+ rdf = subject.to_rdf(model, :predicate => RDF::FOAF.mbox)
357
+ rdf.predicate.must_equal RDF::FOAF.mbox
358
+ end
359
+
360
+ it "can take a value parameter" do
361
+ rdf = subject.to_rdf(model, :value => "George")
362
+ object = rdf.object
363
+ object.to_s.must_equal "George"
364
+ object.must_be_kind_of RDF::Literal
365
+ end
366
+
367
+ it "can take a language parameter" do
368
+ rdf = subject.to_rdf(model, :value => "Jorge", :language => :es)
369
+ rdf.object.language.must_equal :es
370
+ end
371
+
372
+ it "can take a reverse parameter" do
373
+ rdf = subject.to_rdf(model, :value => "George", :reverse => true)
374
+ rdf.subject.to_s.must_equal "George"
375
+ rdf.subject.must_be_kind_of RDF::Literal
376
+ rdf.predicate.must_equal RDF::FOAF.name
377
+ rdf.object.to_s.must_equal model.subject
378
+ rdf.object.must_be_kind_of RDF::URI
379
+ end
380
+
381
+ it "cannot take a subject_decorator as a parameter" do
382
+ def subject.special_subject
383
+ "http://example.com/special_subject"
384
+ end
385
+ rdf = subject.to_rdf(model, :subject_decorator => :special_subject)
386
+ rdf.subject.to_s.must_equal model.subject
387
+ end
388
+
389
+ end # "as prompted from the call parameters"
390
+
391
+ end # to_rdf
392
+
393
+ describe "building from an RDF Statement" do
394
+ describe "when taking a straight RDF::Statement" do
395
+ it "sets the predicate and object" do
396
+ statement = RDF::Statement(:any_subject, RDF::FOAF.name, "George")
397
+ subject = Attribute.new(:statement => statement)
398
+ subject.predicate.must_equal RDF::FOAF.name
399
+ subject.get.must_equal "George"
400
+ end
401
+
402
+ it "captures the language from the object literal" do
403
+ statement = RDF::Statement(:any_subject, RDF::FOAF.name, RDF::Literal.new("Jorge", :language => :es))
404
+ subject = Attribute.new(:statement => statement)
405
+ subject.language.must_equal :es
406
+ end
407
+
408
+ it "captures the datatype from the object literal and serializes correctly" do
409
+ statement = RDF::Statement(:any_subject, RDF::FOAF.name, RDF::Literal.new("1", :datatype => RDF::XSD.integer))
410
+ subject = Attribute.new(:statement => statement)
411
+ subject.datatype.must_equal RDF::XSD.integer
412
+ subject.get.must_equal 1
413
+ end
414
+
415
+ end # "when taking a straight RDF::Statement"
416
+
417
+ describe "when taking an RDF::Statement with a model parameter" do
418
+
419
+ let(:model) do
420
+ Class.new do
421
+ def subject
422
+ "http://example.com/demo/1"
423
+ end
424
+ end.new
425
+ end
426
+
427
+ it "should set reverse when a model is set, and the object equals the model subject" do
428
+ statement = RDF::Statement.new("George", RDF::FOAF.name, "http://example.com/demo/1")
429
+ subject = Attribute.new(:statement => statement, :model => model)
430
+ subject.reverse.must_equal true
431
+ subject.get.must_equal "George"
432
+ subject.predicate.must_equal RDF::FOAF.name
433
+ end
434
+
435
+ it "should proceed as normal if the model subject isn't reversed" do
436
+ object = RDF::Literal.new("1", :datatype => RDF::XSD.integer)
437
+ statement = RDF::Statement(:any_subject, RDF::FOAF.name, object)
438
+ subject = Attribute.new(:statement => statement, :model => model)
439
+ subject.predicate.must_equal RDF::FOAF.name
440
+ subject.get.must_equal 1
441
+ subject.datatype.must_equal RDF::XSD.integer
442
+
443
+ object = RDF::Literal.new("Jorge", :language => :es)
444
+ statement = RDF::Statement(:any_subject, RDF::FOAF.name, object)
445
+ subject = Attribute.new(:statement => statement, :model => model)
446
+ subject.predicate.must_equal RDF::FOAF.name
447
+ subject.get.must_equal "Jorge"
448
+ subject.language.must_equal :es
449
+ end
450
+
451
+ end # "when taking an RDF::Statement with a model parameter"
452
+
453
+ end
454
+
455
+ end