praxis 2.0.pre.4 → 2.0.pre.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +0 -1
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +31 -0
  5. data/Gemfile +1 -1
  6. data/Guardfile +2 -1
  7. data/Rakefile +1 -7
  8. data/TODO.md +28 -0
  9. data/lib/api_browser/package-lock.json +7110 -0
  10. data/lib/praxis.rb +7 -4
  11. data/lib/praxis/action_definition.rb +9 -16
  12. data/lib/praxis/api_general_info.rb +21 -0
  13. data/lib/praxis/application.rb +1 -2
  14. data/lib/praxis/bootloader_stages/routing.rb +2 -4
  15. data/lib/praxis/docs/generator.rb +11 -6
  16. data/lib/praxis/docs/open_api_generator.rb +255 -0
  17. data/lib/praxis/docs/openapi/info_object.rb +39 -0
  18. data/lib/praxis/docs/openapi/media_type_object.rb +59 -0
  19. data/lib/praxis/docs/openapi/operation_object.rb +40 -0
  20. data/lib/praxis/docs/openapi/parameter_object.rb +69 -0
  21. data/lib/praxis/docs/openapi/paths_object.rb +55 -0
  22. data/lib/praxis/docs/openapi/request_body_object.rb +51 -0
  23. data/lib/praxis/docs/openapi/response_object.rb +63 -0
  24. data/lib/praxis/docs/openapi/responses_object.rb +44 -0
  25. data/lib/praxis/docs/openapi/schema_object.rb +87 -0
  26. data/lib/praxis/docs/openapi/server_object.rb +24 -0
  27. data/lib/praxis/docs/openapi/tag_object.rb +21 -0
  28. data/lib/praxis/extensions/attribute_filtering.rb +2 -0
  29. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +148 -157
  30. data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +15 -0
  31. data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +90 -0
  32. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +68 -0
  33. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +58 -0
  34. data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +35 -0
  35. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +12 -24
  36. data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +3 -2
  37. data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +7 -9
  38. data/lib/praxis/extensions/field_selection/field_selector.rb +4 -0
  39. data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +6 -9
  40. data/lib/praxis/extensions/pagination.rb +130 -0
  41. data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +42 -0
  42. data/lib/praxis/extensions/pagination/header_generator.rb +70 -0
  43. data/lib/praxis/extensions/pagination/ordering_params.rb +238 -0
  44. data/lib/praxis/extensions/pagination/pagination_handler.rb +68 -0
  45. data/lib/praxis/extensions/pagination/pagination_params.rb +378 -0
  46. data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +45 -0
  47. data/lib/praxis/handlers/json.rb +2 -0
  48. data/lib/praxis/handlers/www_form.rb +5 -0
  49. data/lib/praxis/handlers/{xml.rb → xml-sample.rb} +6 -0
  50. data/lib/praxis/links.rb +4 -0
  51. data/lib/praxis/mapper/active_model_compat.rb +23 -5
  52. data/lib/praxis/mapper/resource.rb +16 -9
  53. data/lib/praxis/mapper/selector_generator.rb +0 -4
  54. data/lib/praxis/mapper/sequel_compat.rb +1 -0
  55. data/lib/praxis/media_type.rb +1 -56
  56. data/lib/praxis/multipart/part.rb +5 -2
  57. data/lib/praxis/plugins/mapper_plugin.rb +1 -1
  58. data/lib/praxis/plugins/pagination_plugin.rb +71 -0
  59. data/lib/praxis/resource_definition.rb +4 -12
  60. data/lib/praxis/response_definition.rb +1 -1
  61. data/lib/praxis/route.rb +2 -4
  62. data/lib/praxis/routing_config.rb +4 -8
  63. data/lib/praxis/tasks/api_docs.rb +23 -0
  64. data/lib/praxis/tasks/routes.rb +10 -15
  65. data/lib/praxis/types/media_type_common.rb +10 -0
  66. data/lib/praxis/types/multipart_array.rb +62 -0
  67. data/lib/praxis/validation_handler.rb +1 -2
  68. data/lib/praxis/version.rb +1 -1
  69. data/praxis.gemspec +4 -5
  70. data/spec/functional_spec.rb +9 -6
  71. data/spec/praxis/action_definition_spec.rb +4 -16
  72. data/spec/praxis/api_general_info_spec.rb +6 -6
  73. data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +304 -0
  74. data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +39 -0
  75. data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +140 -0
  76. data/spec/praxis/extensions/field_expansion_spec.rb +6 -24
  77. data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +15 -11
  78. data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +4 -3
  79. data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +130 -0
  80. data/spec/praxis/extensions/{field_selection/support → support}/spec_resources_active_model.rb +45 -2
  81. data/spec/praxis/extensions/{field_selection/support → support}/spec_resources_sequel.rb +0 -0
  82. data/spec/praxis/media_type_spec.rb +5 -129
  83. data/spec/praxis/request_spec.rb +3 -22
  84. data/spec/praxis/resource_definition_spec.rb +1 -1
  85. data/spec/praxis/response_definition_spec.rb +8 -9
  86. data/spec/praxis/route_spec.rb +2 -9
  87. data/spec/praxis/routing_config_spec.rb +4 -13
  88. data/spec/praxis/types/multipart_array_spec.rb +4 -21
  89. data/spec/spec_app/config/environment.rb +0 -2
  90. data/spec/spec_app/design/api.rb +7 -1
  91. data/spec/spec_app/design/media_types/instance.rb +0 -8
  92. data/spec/spec_app/design/media_types/volume.rb +0 -12
  93. data/spec/spec_app/design/resources/instances.rb +1 -2
  94. data/spec/spec_helper.rb +6 -0
  95. data/spec/support/spec_media_types.rb +0 -73
  96. metadata +51 -49
  97. data/spec/praxis/handlers/xml_spec.rb +0 -177
  98. data/spec/praxis/links_spec.rb +0 -68
@@ -1,177 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Praxis::Handlers::XML do
4
-
5
- describe '#parse' do
6
- shared_examples 'xml something' do
7
- it 'works' do
8
- expect(subject.parse(parsed.to_xml)).to eq(parsed)
9
- end
10
- end
11
-
12
- # XML_TYPE_NAMES = {
13
- # "Symbol" => "symbol",
14
- # "Fixnum" => "integer",
15
- # "Bignum" => "integer",
16
- # "BigDecimal" => "decimal",
17
- # "Float" => "float",
18
- # "TrueClass" => "boolean",
19
- # "FalseClass" => "boolean",
20
- # "Date" => "date",
21
- # "DateTime" => "dateTime",
22
- # "Time" => "dateTime"
23
- # }
24
-
25
- context "Parsing symbols" do
26
- let(:xml){ '<objects type="array"><object type="symbol">a_symbol</object></objects>' }
27
- let(:parsed){ [:a_symbol] }
28
- it_behaves_like 'xml something'
29
- end
30
-
31
- context "Parsing integers" do
32
- let(:xml){ '<objects type="array"><object type="integer">1234</object></objects>' }
33
- let(:parsed){ [1234] }
34
- it_behaves_like 'xml something'
35
- end
36
-
37
- context "Parsing decimals" do
38
- let(:xml){ '<objects type="array"><object type="decimal">0.1</object></objects>' }
39
- let(:parsed){ [0.1] }
40
- it_behaves_like 'xml something'
41
- end
42
-
43
- context "Parsing floats" do
44
- let(:xml){ '<objects type="array"><object type="float">0.1</object></objects>' }
45
- let(:parsed){ [0.1] }
46
- it_behaves_like 'xml something'
47
- end
48
-
49
- context "Parsing booleans" do
50
- context "that are true" do
51
- let(:xml){ '<objects type="array"><object type="boolean">true</object></objects>' }
52
- let(:parsed){ [true] }
53
- it_behaves_like 'xml something'
54
- end
55
- context "that are false" do
56
- let(:xml){ '<objects type="array"><object type="boolean">false</object></objects>' }
57
- let(:parsed){ [false] }
58
- it_behaves_like 'xml something'
59
-
60
- end
61
- end
62
-
63
- context "Parsing dates" do
64
- let(:xml){ '<objects type="array"><object type="date">2001-01-01</object></objects>' }
65
- let(:parsed){ [Date.parse("2001-01-01")] }
66
- it_behaves_like 'xml something'
67
- end
68
-
69
- context "Parsing dateTimes" do
70
- let(:xml){ '<objects type="array"><object type="dateTime">2015-03-13T19:34:40-07:00</object></objects>' }
71
- let(:parsed){ [DateTime.parse("2015-03-13T19:34:40-07:00")] }
72
- it_behaves_like 'xml something'
73
- end
74
-
75
- context "Parsing hashes" do
76
- context "that are empty" do
77
- let(:xml){ "<hash></hash>" }
78
-
79
- it 'get converted to empty strings' do
80
- expect(subject.parse(xml)).to eq('')
81
- end
82
- end
83
-
84
- context "with a couple of elements" do
85
- let(:xml){ '<hash><one type="integer">1</one><two type="integer">2</two></hash>' }
86
- let(:parsed){ {"one"=>1, "two"=>2} }
87
- it_behaves_like 'xml something'
88
- end
89
- context "with hyphenated elements" do
90
- let(:xml){ '<hash><part-one type="integer">1</part-one><part-two type="integer">2</part-two></hash>' }
91
- let(:parsed){ {"part_one"=>1, "part_two"=>2} }
92
- it_behaves_like 'xml something'
93
- end
94
- context "with a nested hash" do
95
- let(:xml){ '<hash><one type="integer">1</one><sub_hash><first>hello</first></sub_hash></hash>' }
96
- let(:parsed){ {"one"=>1, "sub_hash"=>{"first"=>"hello"} } }
97
- it_behaves_like 'xml something'
98
- end
99
- context "with a nested array" do
100
- let(:xml){ '<hash><one type="integer">1</one><two type="array"><object>just text</object></two></hash>' }
101
- let(:parsed){ {"one"=>1, "two" => ["just text"] } }
102
- it_behaves_like 'xml something'
103
- end
104
-
105
- end
106
-
107
- context "Parsing an Array" do
108
- context 'with a couple of simple elements in it' do
109
- let(:xml){ '<objects type="array"><object>just text</object><object type="integer">1</object></objects>' }
110
- let(:parsed){ ["just text", 1] }
111
- it_behaves_like 'xml something'
112
- end
113
- context "with a nested hash" do
114
- let(:xml){ '<objects type="array"><object>just text</object><object><one type="integer">1</one></object></objects>' }
115
- let(:parsed){ ["just text", { "one" => 1}] }
116
- it_behaves_like 'xml something'
117
- end
118
- end
119
-
120
- context "Parsing XML strings created with .to_xml" do
121
- let(:xml){ parsed.to_xml }
122
- context 'array with a couple of simple elements in it' do
123
- let(:parsed){ ["just text", 1] }
124
- it_behaves_like 'xml something'
125
- end
126
- context 'a hash with a couple of simple elements in it' do
127
- let(:parsed){ { "one"=>"just text", "two"=> 1 } }
128
- it_behaves_like 'xml something'
129
- end
130
- context 'a array with elements of all types' do
131
- let(:parsed){ ["just text",:a,1,BigDecimal(100),0.1,true,Date.new] }
132
- it_behaves_like 'xml something'
133
- end
134
- context 'a hash with a complex substructure' do
135
- let(:parsed) do
136
- Hash(
137
- "text" => "just text",
138
- "symbol" => :a,
139
- "num" => 1,
140
- "bd" => BigDecimal(100),
141
- "float" => 0.1,
142
- "truthyness" => true,
143
- "day" => Date.new,
144
- "empty_string" => ""
145
- )
146
- end
147
- it_behaves_like 'xml something'
148
- end
149
-
150
- context "transformed characters when using .to_xml" do
151
- context 'underscores become dashes' do
152
- let(:xml){ {"one_thing"=>1, "two_things"=>2}.to_xml }
153
- it do
154
- doc = Nokogiri::XML(xml)
155
-
156
- expect(doc.search('one-thing')).to_not be_empty
157
- expect(doc.search('two-things')).to_not be_empty
158
- end
159
- end
160
- context 'spaces become dashes' do
161
- let(:xml){ {"one thing"=>1, "two things"=>2}.to_xml }
162
- let(:parsed){ {"one-thing"=>1, "two-things"=>2} }
163
- it do
164
- doc = Nokogiri::XML(xml)
165
-
166
- expect(doc.search('one-thing')).to_not be_empty
167
- expect(doc.search('two-things')).to_not be_empty
168
- end
169
- end
170
- end
171
- end
172
-
173
- describe '#generate' do
174
- it 'has tests'
175
- end
176
- end
177
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Praxis::Links do
4
- let(:owner_resource) do
5
- double('owner', id: 100, name: /[:name:]/.gen, href: '/')
6
- end
7
-
8
- let(:manager_resource) do
9
- double('manager', id: 101, name: /[:name:]/.gen, href: '/')
10
- end
11
-
12
- let(:resource) do
13
- double('address', id: 1, name: 'Home', owner: owner_resource, manager: manager_resource)
14
- end
15
-
16
- subject(:link) { described_class.for(Address) }
17
-
18
- it 'returns the link class for the media type if defined' do
19
- expect(link.for(Address)).to eq(link)
20
- end
21
-
22
- it 'are marked as anonymous' do
23
- described = link.for(Address).describe
24
- expect(described[:anonymous]).to be(true)
25
- end
26
-
27
- context 'contents' do
28
- subject(:view) { link.view(:default) }
29
-
30
- its(:name) { should eq(:default) }
31
- its(:schema) { should eq(Address::Links) }
32
- its(:contents) { should have_key(:owner) }
33
- its(:contents) { should have_key(:super) }
34
- end
35
-
36
- context 'rendering' do
37
- let(:example){ Address.example }
38
- context 'for :default' do
39
- subject(:rendered_links){ example.render(view: :default)[:links] }
40
-
41
- it 'should use the :link for rendering its attributes' do
42
- example.render(view: :default)[:links]
43
- expect(rendered_links[:owner]).to eq( example.owner.render(view: :link))
44
- end
45
- end
46
- context 'for :master' do
47
- subject(:rendered_links){ example.render(view: :master)[:links] }
48
- it 'should use the :link for rendering its attributes' do
49
- expect(rendered_links[:owner]).to eq( example.owner.render(view: :link))
50
- end
51
- end
52
- end
53
-
54
- context '.example' do
55
- subject(:example) { Address.example }
56
-
57
- its('links.owner') { should be(example.owner) }
58
- its('links.super') { should be(example.object.manager) }
59
-
60
- it 'does not respond to non-top-level attributes from links' do
61
- expect { example.super }.to raise_error(NoMethodError)
62
- end
63
-
64
- it 'responds to non-top-level attributes from links on its inner Struct' do
65
- expect(example.links.super).to be(example.object.manager)
66
- end
67
- end
68
- end