gearbox 0.1.0 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
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