icss-activesupport-4 0.4.0

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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.rspec +3 -0
  4. data/.watchr +52 -0
  5. data/CHANGELOG.md +38 -0
  6. data/Gemfile +22 -0
  7. data/LICENSE.textile +20 -0
  8. data/README.md +298 -0
  9. data/Rakefile +39 -0
  10. data/TODO.md +44 -0
  11. data/VERSION +1 -0
  12. data/examples/avro_examples/BulkData.avpr +21 -0
  13. data/examples/avro_examples/complicated.icss.yaml +159 -0
  14. data/examples/avro_examples/interop.avsc +32 -0
  15. data/examples/avro_examples/mail.avpr +20 -0
  16. data/examples/avro_examples/namespace.avpr +28 -0
  17. data/examples/avro_examples/org/apache/avro/ipc/HandshakeRequest.avsc +11 -0
  18. data/examples/avro_examples/org/apache/avro/ipc/HandshakeResponse.avsc +15 -0
  19. data/examples/avro_examples/org/apache/avro/ipc/trace/avroTrace.avdl +64 -0
  20. data/examples/avro_examples/org/apache/avro/ipc/trace/avroTrace.avpr +82 -0
  21. data/examples/avro_examples/org/apache/avro/mapred/tether/InputProtocol.avpr +59 -0
  22. data/examples/avro_examples/org/apache/avro/mapred/tether/OutputProtocol.avpr +75 -0
  23. data/examples/avro_examples/simple.avpr +70 -0
  24. data/examples/avro_examples/weather.avsc +9 -0
  25. data/examples/bnc.icss.yaml +70 -0
  26. data/examples/chronic.icss.yaml +115 -0
  27. data/examples/license.icss.yaml +7 -0
  28. data/examples/source1.icss.yaml +4 -0
  29. data/examples/source2.icss.yaml +4 -0
  30. data/examples/test_icss.yaml +67 -0
  31. data/icss.gemspec +168 -0
  32. data/icss_specification.textile +393 -0
  33. data/lib/icss.rb +53 -0
  34. data/lib/icss/core_types.rb +20 -0
  35. data/lib/icss/error.rb +4 -0
  36. data/lib/icss/init.rb +3 -0
  37. data/lib/icss/message.rb +133 -0
  38. data/lib/icss/message/message_sample.rb +144 -0
  39. data/lib/icss/protocol.rb +199 -0
  40. data/lib/icss/protocol/code_asset.rb +18 -0
  41. data/lib/icss/protocol/data_asset.rb +23 -0
  42. data/lib/icss/protocol/license.rb +41 -0
  43. data/lib/icss/protocol/source.rb +37 -0
  44. data/lib/icss/protocol/target.rb +68 -0
  45. data/lib/icss/receiver_model.rb +24 -0
  46. data/lib/icss/receiver_model/active_model_shim.rb +36 -0
  47. data/lib/icss/receiver_model/acts_as_catalog.rb +174 -0
  48. data/lib/icss/receiver_model/acts_as_hash.rb +177 -0
  49. data/lib/icss/receiver_model/acts_as_loadable.rb +47 -0
  50. data/lib/icss/receiver_model/acts_as_tuple.rb +100 -0
  51. data/lib/icss/receiver_model/locale/en.yml +27 -0
  52. data/lib/icss/receiver_model/to_geo_json.rb +19 -0
  53. data/lib/icss/receiver_model/tree_merge.rb +34 -0
  54. data/lib/icss/receiver_model/validations.rb +31 -0
  55. data/lib/icss/serialization.rb +51 -0
  56. data/lib/icss/serialization/zaml.rb +442 -0
  57. data/lib/icss/type.rb +168 -0
  58. data/lib/icss/type/base_type.rb +0 -0
  59. data/lib/icss/type/named_type.rb +185 -0
  60. data/lib/icss/type/record_field.rb +77 -0
  61. data/lib/icss/type/record_model.rb +49 -0
  62. data/lib/icss/type/record_schema.rb +54 -0
  63. data/lib/icss/type/record_type.rb +325 -0
  64. data/lib/icss/type/simple_types.rb +71 -0
  65. data/lib/icss/type/structured_schema.rb +288 -0
  66. data/lib/icss/type/type_factory.rb +144 -0
  67. data/lib/icss/type/union_schema.rb +41 -0
  68. data/lib/icss/view_helper.rb +65 -0
  69. data/notes/named_array.md +32 -0
  70. data/notes/on_include_vs_extend_etc.rb +176 -0
  71. data/notes/technical_details.md +278 -0
  72. data/spec/core_types_spec.rb +119 -0
  73. data/spec/fixtures/zaml_complex_hash.yaml +35 -0
  74. data/spec/icss_spec.rb +90 -0
  75. data/spec/message/message_sample_spec.rb +4 -0
  76. data/spec/message_spec.rb +139 -0
  77. data/spec/protocol/license_spec.rb +67 -0
  78. data/spec/protocol/protocol_catalog_spec.rb +48 -0
  79. data/spec/protocol/protocol_validations_spec.rb +176 -0
  80. data/spec/protocol/source_spec.rb +65 -0
  81. data/spec/protocol_spec.rb +170 -0
  82. data/spec/receiver_model_spec.rb +115 -0
  83. data/spec/serialization/zaml_spec.rb +82 -0
  84. data/spec/serialization/zaml_test.rb +473 -0
  85. data/spec/serialization_spec.rb +63 -0
  86. data/spec/spec_helper.rb +39 -0
  87. data/spec/support/icss_test_helper.rb +67 -0
  88. data/spec/support/load_example_protocols.rb +17 -0
  89. data/spec/type/base_type_spec.rb +0 -0
  90. data/spec/type/named_type_spec.rb +75 -0
  91. data/spec/type/record_field_spec.rb +44 -0
  92. data/spec/type/record_model_spec.rb +206 -0
  93. data/spec/type/record_schema_spec.rb +161 -0
  94. data/spec/type/record_type_spec.rb +155 -0
  95. data/spec/type/simple_types_spec.rb +121 -0
  96. data/spec/type/structured_schema_spec.rb +300 -0
  97. data/spec/type/type_catalog_spec.rb +44 -0
  98. data/spec/type/type_factory_spec.rb +93 -0
  99. data/spec/type/union_schema_spec.rb +0 -0
  100. data/spec/type_spec.rb +63 -0
  101. metadata +304 -0
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'icss'
3
+
4
+ describe Icss::Meta::Protocol do
5
+ before do
6
+ Icss::Meta::Protocol.send :flush_registry
7
+ Icss::Meta::Protocol._catalog_loaded = true #prevent automatic loading of catalog
8
+ end
9
+ let(:protocol){ Icss::Meta::Protocol.receive(:protocol => 'test', :namespace => 'name.space') }
10
+
11
+ # Calling receive adds protocol to registry with after_receiver
12
+ describe :registry do
13
+ specify { Icss::Meta::Protocol.registry.should include('name.space.test' => protocol) }
14
+ end
15
+
16
+ describe '#find' do
17
+ context 'specific protocol name parameters' do
18
+ before { protocol } # load protocol into registry
19
+ it('return protocol'){ Icss::Meta::Protocol.find('name.space.test').should == protocol }
20
+ it('should error if not found'){ lambda{ Icss::Meta::Protocol.find('name.space.not.found') }.should raise_error(Icss::NotFoundError) }
21
+ it('should error for wildcard name'){ lambda{ Icss::Meta::Protocol.find('name.*.test') }.should raise_error(Icss::NotFoundError) }
22
+ end
23
+
24
+ context 'wildcard protocol name parameters' do
25
+ before { protocol } # load protocol into registry
26
+ context ':all' do
27
+ it('accepts wilcard names'){ Icss::Meta::Protocol.find(:all, 'name.*').should == [protocol] }
28
+ it('returns empty array if not found'){ Icss::Meta::Protocol.find(:all, 'not.*.found').should == [] }
29
+ end
30
+
31
+ context ':first' do
32
+ it('accepts wilcard names'){ Icss::Meta::Protocol.find(:first, 'name.*').should == protocol }
33
+ it('returns nil if not found'){ Icss::Meta::Protocol.find(:first, 'not.*.found').should be_nil }
34
+ end
35
+
36
+ context ':last' do
37
+ it('accepts wilcard names'){ Icss::Meta::Protocol.find(:last, 'name.*').should == protocol }
38
+ it('returns nil if not found'){ Icss::Meta::Protocol.find(:last, 'not.*.found').should be_nil }
39
+ end
40
+ end
41
+ end
42
+ describe '#all, #first, #last' do
43
+ before { protocol } # load protocol into registry
44
+ it('#all returns all protocols'){ Icss::Meta::Protocol.all.should == [protocol] }
45
+ it('#first returns first of all protocols'){ Icss::Meta::Protocol.first.should == protocol }
46
+ it('#last returns last of all protocols'){ Icss::Meta::Protocol.last.should == protocol }
47
+ end
48
+ end
@@ -0,0 +1,176 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'icss'
4
+
5
+ def template_icss
6
+ return <<EOS
7
+ ---
8
+ namespace: foo.bar
9
+ protocol: baz
10
+
11
+ data_assets:
12
+ - name: test_data_asset
13
+ location: data/test_data.tsv
14
+ type: test_data_record
15
+
16
+ messages:
17
+ search:
18
+ doc: A testable template message
19
+ request:
20
+ - name: test_request
21
+ type: test_request_record
22
+ response: test_data_record
23
+ samples:
24
+ - request:
25
+ - first_param: foo
26
+ second_param: bar
27
+
28
+ targets:
29
+ catalog:
30
+ - name: test_catalog_entry
31
+ title: Test Icss
32
+ description: This is a template Icss to test the error handling of the Icss library.
33
+ tags:
34
+ - test
35
+ - icss
36
+ - template
37
+ messages:
38
+ - search
39
+ packages:
40
+ - data_assets:
41
+ - test_data_asset
42
+
43
+ types:
44
+ - name: test_request_record
45
+ doc: A template request record
46
+ type: record
47
+ fields:
48
+ - name: first_param
49
+ doc: The first test parameter
50
+ type: string
51
+ - name: second param
52
+ doc: The second test parameter
53
+ type: string
54
+
55
+ - name: test_complex_data
56
+ doc: A template complex data type
57
+ type: record
58
+ fields:
59
+ - name: field_one
60
+ doc: A simple field for a complex data type
61
+ type: string
62
+ - name: field_two
63
+ doc: Another simple field for a complex data type
64
+ type: string
65
+
66
+ - name: test_data_record
67
+ doc: A template data record
68
+ type: record
69
+ fields:
70
+ - name: simple_data
71
+ doc: A simple piece of data
72
+ type: int
73
+ - name: complex_data
74
+ doc: A complex piece of data
75
+ type: test_complex_data
76
+
77
+ EOS
78
+ end
79
+
80
+ describe "Icss::Meta::Protocol validations" do
81
+ before :each do
82
+ @template = YAML.load(template_icss)
83
+ end
84
+
85
+ after :all do
86
+ Icss::Meta::TypeFactory.send :remove_instance_variable, :"@default_namespace"
87
+ end
88
+
89
+ it "should be able to receive a correctly formatted template Icss" do
90
+ lambda { @icss =Icss::Meta::Protocol.receive @template }.should_not raise_error
91
+ @icss.errors.should be_empty
92
+ end
93
+
94
+ it "should contain keys for all fields even if not included in the Icss file" do
95
+ @icss = Icss::Meta::Protocol.receive @template
96
+ @icss.keys.map{|k| k.to_s }.sort.should == (@template.keys | %w[code_assets _doc_hints _extra_params tags categories credits doc title]).sort
97
+ end
98
+
99
+ it "should generate an error when the namespace is formatted incorrectly" do
100
+ @template['namespace'] = '$bad_namespace'
101
+ Icss::Meta::Protocol.receive(@template).errors.keys.should == [:namespace]
102
+ end
103
+
104
+ it "should generate an error when the protocol is formatted incorrectly" do
105
+ @template['protocol'] = '$bad_protocol'
106
+ Icss::Meta::Protocol.receive(@template).errors.keys.should == [:protocol]
107
+ end
108
+
109
+ # context "Catalog Target" do
110
+ #
111
+ # it "should generate an error when an undefined data_asset is specified" do
112
+ # @template['targets']['catalog'].first['packages'].first['data_assets'] = ['fake_data_asset']
113
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:catalog]
114
+ # end
115
+ #
116
+ # it "should generate an error when an undefined message name is specified" do
117
+ # @template['targets']['catalog'].first['messages'] = ['fake_message']
118
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:catalog]
119
+ # end
120
+ #
121
+ # end
122
+ #
123
+ # context "Data Assets" do
124
+ #
125
+ # it "should generate an error when an asset's type is undefined" do
126
+ # @template['data_assets'].first['type'] = 'fake_data_asset'
127
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:data_assets]
128
+ # end
129
+ #
130
+ # end
131
+ #
132
+ # context "Messages" do
133
+ #
134
+ # it "should generate an error when a message's request type is undefined" do
135
+ # @template['messages']['search']['request'].first['type'] = 'fake_request_type'
136
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:messages]
137
+ # end
138
+ #
139
+ # it "should generate an error when a message's response type is undefined" do
140
+ # @template['messages']['search']['response'] = 'fake_response_type'
141
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:messages]
142
+ # end
143
+ #
144
+ # it "should generate an error when a message's sample request types do not match the request record" do
145
+ # @template['messages']['search']['samples'].first['request'] = [{ 'foo' => 'bar' }]
146
+ # Icss::Meta::Protocol.receive(@template).errors.keys.should == [:messages]
147
+ # end
148
+ #
149
+ # end
150
+
151
+ context "Types" do
152
+
153
+ it "should raise an error when an bad type definition is given for a specific type" do
154
+ @template['types'].push({
155
+ 'name' => 'fake_type_record',
156
+ 'type' => 'fake'
157
+ })
158
+ lambda{ Icss::Meta::Protocol.receive(@template) }.should raise_error(Icss::NotFoundError, /Cannot find.*fake/)
159
+ end
160
+
161
+ it "should generate an error when an undefined type definition is given for a specific field" do
162
+ @template['types'].push({
163
+ 'name' => 'fake_type_record',
164
+ 'type' => 'record',
165
+ 'fields' => [{
166
+ 'name' => 'fake_field',
167
+ 'type' => 'fake_type'
168
+ }]
169
+ })
170
+ lambda{ Icss::Meta::Protocol.receive(@template) }.should raise_error(Icss::NotFoundError, /Cannot find.*fake_type/)
171
+
172
+ end
173
+
174
+ end
175
+
176
+ end
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'icss'
3
+
4
+ describe Icss::Meta::Source do
5
+ before do
6
+ Icss::Meta::Source.send :flush_registry
7
+ Icss::Meta::Source._catalog_loaded = true #prevent automatic loading of catalog
8
+ end
9
+ let(:source){ Icss::Meta::Source.receive(:source_id => 'sources.test', :title => 'Test source', :description => 'Source description', :url => 'http://test.com') }
10
+
11
+ describe '#name' do
12
+ specify { source.name.should == 'test' }
13
+ end
14
+
15
+ describe '#fullname' do
16
+ specify { source.fullname.should == 'sources.test' }
17
+ end
18
+
19
+
20
+
21
+ # Calling receive adds source to registry with after_receiver
22
+ describe :registry do
23
+ specify { Icss::Meta::Source.registry.should include('sources.test' => source) }
24
+ end
25
+
26
+ describe '#find' do
27
+ context 'specific source name parameters' do
28
+ before { source } # load source into registry
29
+ it('return source'){ Icss::Meta::Source.find('sources.test').should == source }
30
+ it('should error if not found'){ lambda{ Icss::Meta::Source.find('sources.not_found') }.should raise_error(Icss::NotFoundError) }
31
+ it('should error for wildcard name'){ lambda{ Icss::Meta::Source.find('sources.*.test') }.should raise_error(Icss::NotFoundError) }
32
+ end
33
+
34
+ context 'wildcard source name parameters' do
35
+ before { source } # load source into registry
36
+ context ':all' do
37
+ it('accepts wilcard names'){ Icss::Meta::Source.find(:all, 'sources.*').should == [source] }
38
+ it('returns empty array if not found'){ Icss::Meta::Source.find(:all, 'not.*.found').should == [] }
39
+ end
40
+
41
+ context ':first' do
42
+ it('accepts wilcard names'){ Icss::Meta::Source.find(:first, 'sources.*').should == source }
43
+ it('returns nil if not found'){ Icss::Meta::Source.find(:first, 'not.*.found').should be_nil }
44
+ end
45
+
46
+ context ':last' do
47
+ it('accepts wilcard names'){ Icss::Meta::Source.find(:last, 'sources.*').should == source }
48
+ it('returns nil if not found'){ Icss::Meta::Source.find(:last, 'not.*.found').should be_nil }
49
+ end
50
+ end
51
+ end
52
+ describe '#all, #first, #last' do
53
+ before { source } # load source into registry
54
+ it('#all returns all sources'){ Icss::Meta::Source.all.should == [source] }
55
+ it('#first returns first of all sources'){ Icss::Meta::Source.first.should == source }
56
+ it('#last returns last of all sources'){ Icss::Meta::Source.last.should == source }
57
+ end
58
+
59
+ describe '#to_hash' do
60
+ it { source.to_hash.should == {:source_id => 'sources.test',
61
+ :title => 'Test source',
62
+ :description => 'Source description',
63
+ :url => 'http://test.com'}}
64
+ end
65
+ end
@@ -0,0 +1,170 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'icss'
3
+
4
+ describe Icss::Meta::Protocol do
5
+
6
+ let(:simple_icss) do
7
+ Icss::Meta::Protocol.receive_from_file(ENV.root_path('examples/chronic.icss.yaml'))
8
+ end
9
+
10
+ it 'loads cleanly' do
11
+ simple_icss.basename.should == 'chronic'
12
+ simple_icss.fullname.should == 'st.time_utils.chronic'
13
+ end
14
+
15
+ describe '#fullname' do
16
+ it 'has namespace and basename' do
17
+ simple_icss.fullname.should == 'st.time_utils.chronic'
18
+ simple_icss.namespace = nil
19
+ simple_icss.fullname.should == 'chronic'
20
+ end
21
+ end
22
+ describe '#path' do
23
+ it 'is a / separated version of the name, with no / at start' do
24
+ simple_icss.path.should == 'st/time_utils/chronic'
25
+ end
26
+ end
27
+ describe '#doc' do
28
+ it 'takes a doc string' do
29
+ simple_icss.doc.should == 'A series of calls hooking into the Chronic ruby gem'
30
+ end
31
+ end
32
+
33
+ describe 'types' do
34
+ it 'has an array of types' do
35
+ simple_icss.types.map(&:basename).should == ['chronic_parse_params', 'chronic_parse_response']
36
+ end
37
+ end
38
+
39
+ describe 'messages' do
40
+ it 'has a hash of messages' do
41
+ simple_icss.messages.keys.should == ['parse']
42
+ end
43
+
44
+ it 'named each message for its key' do
45
+ simple_icss.messages['parse'].basename.should == 'parse'
46
+ simple_icss.receive!({ :messages => { 'foo' => { :request => [] } }})
47
+ simple_icss.messages['foo'].basename.should == 'foo'
48
+ end
49
+
50
+ it '#find_message' do
51
+ msg = simple_icss.find_message(:parse)
52
+ msg.should be_a(Icss::Meta::Message) ; msg.basename.should == 'parse'
53
+ msg = simple_icss.find_message('st.time_utils.parse')
54
+ msg.should be_a(Icss::Meta::Message) ; msg.basename.should == 'parse'
55
+ msg = simple_icss.find_message('st/time_utils/parse')
56
+ msg.should be_a(Icss::Meta::Message) ; msg.basename.should == 'parse'
57
+ end
58
+ end
59
+
60
+ describe 'targets' do
61
+ it 'has a hash of targets' do
62
+ simple_icss.targets.keys.should == [:catalog]
63
+ simple_icss.targets[:catalog].first.should be_a(Icss::CatalogTarget)
64
+ simple_icss.targets[:catalog].first.basename.should == 'st_time_utils_chronic_parse'
65
+ end
66
+ end
67
+
68
+ describe 'license' do
69
+ it 'returns nil if no license_id specified' do
70
+ simple_icss.license.should be_nil
71
+ end
72
+ it 'raises Icss::NotFoundError if license_id specified and not found' do
73
+ simple_icss.license_id = 'not_found_license'
74
+ lambda{ simple_icss.license }.should raise_error(Icss::NotFoundError, /Cannot find .*/)
75
+ end
76
+ it 'returns the Icss::Meta::License object' do
77
+ license = Icss::Meta::License.receive_from_file(ENV.root_path('examples/license.icss.yaml'))
78
+ simple_icss.license_id = 'licenses.example'
79
+ simple_icss.license.should == license
80
+ end
81
+ end
82
+
83
+
84
+
85
+ describe 'sources' do
86
+ it 'returns empty array if no source_ids specified' do
87
+ simple_icss.sources.should == {}
88
+ end
89
+ it 'raises Icss::NotFoundError if license_id specified and not found' do
90
+ simple_icss.credits = { :role => 'not_found_license' }
91
+ lambda{ simple_icss.sources }.should raise_error(Icss::NotFoundError, /Cannot find .*/)
92
+ end
93
+ it 'returns array of Icss::Meta::Source objects' do
94
+ source2 = Icss::Meta::Source.receive_from_file(ENV.root_path('examples/source2.icss.yaml'))
95
+ source1 = Icss::Meta::Source.receive_from_file(ENV.root_path('examples/source1.icss.yaml'))
96
+ simple_icss.credits = {:main => 'sources.source1', :uploaded => 'sources.source2'}
97
+ simple_icss.sources.should == { :main => source1, :uploaded => source2 }
98
+ end
99
+ end
100
+
101
+ describe 'validations' do
102
+ it 'validates protocol name' do
103
+ simple_icss.should be_valid
104
+ simple_icss.protocol = '' ; simple_icss.should_not be_valid ; simple_icss.errors[:protocol].should include("can't be blank")
105
+ simple_icss.protocol = '1bz' ; simple_icss.should_not be_valid ; simple_icss.errors[:protocol].should include("must start with [A-Za-z_] and contain only [A-Za-z0-9_].")
106
+ end
107
+
108
+ it 'validates namespace' do
109
+ simple_icss.should be_valid
110
+ simple_icss.namespace = '' ; simple_icss.should_not be_valid ; simple_icss.errors[:namespace].should include("can't be blank")
111
+ simple_icss.namespace = '1bz' ; simple_icss.should_not be_valid ; simple_icss.errors[:namespace].first.should =~ /Segments that start with.*joined by.*dots/
112
+ end
113
+ end
114
+
115
+ describe '#to_hash' do
116
+ it 'roundtrips' do
117
+ simple_icss.license_id = 'licenses.example'
118
+ simple_icss.credits = { :original => 'sources.source1' }
119
+ simple_icss.tags = ['tag1', 'tag2', 'tag3']
120
+ simple_icss.categories = ['category1', 'category2', 'category3']
121
+ hsh = simple_icss.to_hash
122
+ hsh.should == {
123
+ :namespace=>"st.time_utils", :protocol=>"chronic",
124
+ :doc=>"A series of calls hooking into the Chronic ruby gem",
125
+ :license_id=>"licenses.example",
126
+ :credits=>{:original=>"sources.source1"},
127
+ :tags=>['tag1', 'tag2', 'tag3'],
128
+ :categories=>['category1', 'category2', 'category3'],
129
+ :types => [
130
+ {:name=>"st.time_utils.chronic_parse_params",
131
+ :namespace=>"st.time_utils",
132
+ :type=>:record,
133
+ :doc=>"Query API parameters for the /st/time_utils/chronic/parse call",
134
+ :fields=>[
135
+ {:name=>:time_str, :type=>:string, :doc=>"The string to parse."},
136
+ {:name=>:context, :type=>:symbol, :doc=>"<tt>past</tt> or <tt>future</tt> (defaults to <tt>future</tt>)\nIf your string represents a birthday, you can set <tt>context</tt> to <tt>past</tt> and if an ambiguous string is given, it will assume it is in the past. Specify <tt>future</tt> or omit to set a future context."},
137
+ {:name=>:now, :type=>:time, :doc=>"Time (defaults to Time.now)\nBy setting <tt>:now</tt> to a Time, all computations will be based off of that time instead of Time.now. If set to nil, Chronic will use the current time in UTC. You must supply a date that unambiguously parses with the much-less-generous ruby Time.parse()"},
138
+ {:name=>:ambiguous_time_range, :type=>:int, :doc=>"Integer or <tt>:none</tt> (defaults to <tt>6</tt> (6am-6pm))\nIf an Integer is given, ambiguous times (like 5:00) will be assumed to be within the range of that time in the AM to that time in the PM. For example, if you set it to <tt>7</tt>, then the parser will look for the time between 7am and 7pm. In the case of 5:00, it would assume that means 5:00pm. If <tt>:none</tt> is given, no assumption will be made, and the first matching instance of that time will be used."}
139
+ ]},
140
+ {:name=>"st.time_utils.chronic_parse_response",
141
+ :namespace=>"st.time_utils",
142
+ :type=>:record,
143
+ :doc=>"Query API response for the /util/time/chronic/parse call",
144
+ :fields=>[
145
+ {:name=>:time, :type=>:string, :doc=>"The UTC parsed time, as a \"ISO 8601 combined date time\":http://en.wikipedia.org/wiki/ISO_8601 string."},
146
+ {:name=>:epoch_seconds, :type=>:int, :doc=>"The UTC parsed time, as \"epoch seconds\":http://en.wikipedia.org/wiki/Epoch_seconds integer."}
147
+ ]}
148
+ ],
149
+ :messages => {
150
+ :parse => {
151
+ :request =>[{:name=>:chronic_parse_params, :type=>"st.time_utils.chronic_parse_params"}],
152
+ :response =>"st.time_utils.chronic_parse_response",
153
+ :doc=>"\nChronic is a natural language date/time parser written in pure Ruby. See below\nfor the wide variety of formats Chronic will parse.",
154
+ :samples =>[{
155
+ :request=>[{"time_str"=>"one hour ago", "now"=>"2007-03-16T12:09:08Z"}],
156
+ :response=>{"epoch_seconds"=>1174043348, "time"=>"2007-03-16T11:09:08Z"}, :url=>"?now=2007-03-16T12%3A09%3A08Z&time_str=one%20hour%20ago"},
157
+ {:request=>[{"time_str"=>"Yesterday", "now"=>"5:06:07T2010-08-08Z"}],
158
+ :response=>{"epoch_seconds"=>1281182400, "time"=>"2010-08-07T12:00:00Z"}, :url=>"?now=5%3A06%3A07%202010-08-08&time_str=Yesterday"},
159
+ {:url=>"?time_str=5pm+on+November+4th&context=past"}]
160
+ },
161
+ },
162
+ :data_assets=>[],
163
+ :code_assets=>[{:location=>"code/chronic_endpoint.rb"}],
164
+ :targets => {:catalog=>[{:name=>"st_time_utils_chronic_parse", :title=>"Utils - Parse Times", :description=>"An API call to parse human-readable date / time strings", :tags=>["apiawesome", "ruby", "gems", "chronic", "time", "date", "util", "parse"], :messages=>["parse"]}]},
165
+ }
166
+ end
167
+ end
168
+
169
+ end
170
+