simple_json_api 0.0.2

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 (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.overcommit.yml +31 -0
  4. data/.rubocop.yml +8 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +21 -0
  7. data/LICENSE +22 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +37 -0
  10. data/Rakefile +22 -0
  11. data/lib/simple_json_api.rb +27 -0
  12. data/lib/simple_json_api/active_record_refinements.rb +21 -0
  13. data/lib/simple_json_api/array_refinements.rb +14 -0
  14. data/lib/simple_json_api/array_serializer.rb +16 -0
  15. data/lib/simple_json_api/association.rb +10 -0
  16. data/lib/simple_json_api/attribute.rb +9 -0
  17. data/lib/simple_json_api/dsl.rb +61 -0
  18. data/lib/simple_json_api/field_list.rb +33 -0
  19. data/lib/simple_json_api/include_list.rb +20 -0
  20. data/lib/simple_json_api/json_api_builder.rb +92 -0
  21. data/lib/simple_json_api/resource_serializer.rb +68 -0
  22. data/lib/simple_json_api/serializer.rb +52 -0
  23. data/lib/simple_json_api/version.rb +4 -0
  24. data/simple_json_api.gemspec +34 -0
  25. data/test/fixtures/projects.yml +5 -0
  26. data/test/integration/render_basic_test.rb +71 -0
  27. data/test/integration/render_fields_test.rb +78 -0
  28. data/test/integration/render_include_test.rb +133 -0
  29. data/test/integration/render_nested_include_test.rb +116 -0
  30. data/test/integration/serializers_test.rb +41 -0
  31. data/test/setup/data.rb +24 -0
  32. data/test/setup/models.rb +49 -0
  33. data/test/setup/schema.rb +38 -0
  34. data/test/setup/serializers.rb +57 -0
  35. data/test/test_helper.rb +33 -0
  36. data/test/test_setup.rb +19 -0
  37. data/test/tmp/schema.rb +47 -0
  38. data/test/unit/association_test.rb +28 -0
  39. data/test/unit/attribute_test.rb +22 -0
  40. data/test/unit/field_list_test.rb +28 -0
  41. data/test/unit/include_list_test.rb +23 -0
  42. metadata +241 -0
@@ -0,0 +1,116 @@
1
+ require 'test_helper'
2
+
3
+ # SimpleJsonApi
4
+ module SimpleJsonApi
5
+ describe 'RenderNestedIncludeTest' do
6
+ it 'should match json hash for a project with nested includes specified' do
7
+ compare_json(actual_project, expected_project.to_json)
8
+ JSON.parse(actual_project).must_equal expected_project
9
+ end
10
+
11
+ let(:actual_project) do
12
+ SimpleJsonApi.render(
13
+ model: Project.first,
14
+ serializer: ProjectSerializer,
15
+ options: {
16
+ include: 'todolists'\
17
+ ',todolists.todos'\
18
+ ',todolists.todos.tags'\
19
+ ',todolists.todos.tags.taggables',
20
+ fields: { projects: 'id', todolists: 'id', todos: 'id', tags: 'guid' }
21
+ }
22
+ )
23
+ end
24
+ let(:expected_project) do
25
+ {
26
+ 'projects' => {
27
+ 'id' => '100',
28
+ 'href' => 'http://example.com/projects/100',
29
+ 'links' => {
30
+ 'todolist' => '200',
31
+ 'tags' => ['10']
32
+ }
33
+ },
34
+ 'linked' => {
35
+ 'todolists' => [
36
+ {
37
+ 'id' => '200',
38
+ 'href' => 'http://example.com/todolists/200',
39
+ 'links' => {
40
+ 'todos' => ['300'],
41
+ 'tags' => ['30']
42
+ }
43
+ }
44
+ ],
45
+ 'todos' => [
46
+ {
47
+ 'id' => '300',
48
+ 'href' => 'http://example.com/todos/300',
49
+ 'links' => {
50
+ 'tags' => %w(10 20)
51
+ }
52
+ },
53
+ {
54
+ 'id' => '330',
55
+ 'href' => 'http://example.com/todos/330',
56
+ 'links' => {
57
+ 'tags' => ['10']
58
+ }
59
+ },
60
+ # FIXME: duplicate!!!!!
61
+ {
62
+ 'id' => '300',
63
+ 'href' => 'http://example.com/todos/300',
64
+ 'links' => {
65
+ 'tags' => %w(10 20)
66
+ }
67
+ }
68
+ ],
69
+ 'tags' => [
70
+ {
71
+ 'guid' => '10',
72
+ 'links' => {
73
+ 'taggables' => [
74
+ %w(projects 100),
75
+ %w(todos 300),
76
+ %w(todos 330)
77
+ ]
78
+ }
79
+ },
80
+ {
81
+ 'guid' => '20',
82
+ 'links' => {
83
+ 'taggables' => [
84
+ %w(projects 110),
85
+ %w(todos 300)
86
+ ]
87
+ }
88
+ }
89
+ ],
90
+ 'projects' => [
91
+ {
92
+ 'id' => '100',
93
+ 'href' => 'http://example.com/projects/100',
94
+ 'links' => {
95
+ 'todolist' => '200',
96
+ 'tags' => [
97
+ '10'
98
+ ]
99
+ }
100
+ },
101
+ {
102
+ 'id' => '110',
103
+ 'href' => 'http://example.com/projects/110',
104
+ 'links' => {
105
+ 'todolist' => '210',
106
+ 'tags' => [
107
+ '20'
108
+ ]
109
+ }
110
+ }
111
+ ]
112
+ }
113
+ }
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ # SimpleJsonApi
4
+ module SimpleJsonApi
5
+ describe 'SerializersTest' do
6
+ it 'should have registered serializers' do
7
+ expected = [
8
+ {
9
+ serializer: TagSerializer,
10
+ resource: :tags,
11
+ primary_key: :guid,
12
+ model: Tag
13
+ },
14
+ {
15
+ serializer: TaggingSerializer,
16
+ resource: :taggings,
17
+ primary_key: :id
18
+ },
19
+ {
20
+ serializer: TodoSerializer,
21
+ resource: :todos,
22
+ primary_key: :id,
23
+ model: Todo
24
+ },
25
+ {
26
+ serializer: TodolistSerializer,
27
+ resource: :todolists,
28
+ primary_key: :id,
29
+ model: Todolist
30
+ },
31
+ {
32
+ serializer: ProjectSerializer,
33
+ resource: :projects,
34
+ model: Project,
35
+ primary_key: :id
36
+ }
37
+ ]
38
+ ResourceSerializer.registered_serializers.must_equal expected
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ tag1 = Tag.create(guid: 10, name: 'Urgent!')
2
+ tag2 = Tag.create(guid: 20, name: 'On Hold')
3
+ tag3 = Tag.create(guid: 30, name: 'Favorite')
4
+
5
+ project1 = Project.create(id: 100,
6
+ name: 'First Project',
7
+ description: 'The first project')
8
+ project1.tags << tag1
9
+ project2 = Project.create(id: 110,
10
+ name: 'Second Project',
11
+ description: 'The second project')
12
+ project2.tags << tag2
13
+
14
+ list1 = project1.create_todolist(id: 200, description: 'Groceries')
15
+ list1.tags << tag3
16
+ todo1 = list1.todos.create(id: 300, action: 'Milk')
17
+ todo1.tags << tag1
18
+ todo1.tags << tag2
19
+
20
+ list2 = project2.create_todolist(id: 210, description: 'Work')
21
+ list2.todos.create(id: 310, action: 'Timesheet')
22
+ list2.todos.create(id: 320, action: 'Meeting')
23
+ todo2 = list2.todos.create(id: 330, action: 'Bread')
24
+ todo2.tags << tag1
@@ -0,0 +1,49 @@
1
+ # Project for testing
2
+ class Project < ActiveRecord::Base
3
+ has_one :todolist
4
+ has_many :taggings, as: :taggable, class_name: 'Tagging'
5
+ has_many :tags, through: :taggings, source: :tag, class_name: 'Tag'
6
+ end
7
+
8
+ # Todolist for testing
9
+ class Todolist < ActiveRecord::Base
10
+ belongs_to :project
11
+ has_many :todos
12
+ has_many :taggings, as: :taggable, class_name: 'Tagging'
13
+ has_many :tags, through: :taggings, source: :tag, class_name: 'Tag'
14
+ end
15
+
16
+ # To_do: misspelled so it won't be mistaken for the similarly named thing
17
+ class Todo < ActiveRecord::Base
18
+ belongs_to :todolist
19
+ has_many :taggings, as: :taggable, class_name: 'Tagging'
20
+ has_many :tags, through: :taggings, source: :tag, class_name: 'Tag'
21
+ end
22
+
23
+ # Tagging for testing
24
+ class Tagging < ActiveRecord::Base
25
+ belongs_to :tag
26
+ belongs_to :taggable, polymorphic: true
27
+ end
28
+
29
+ # Tag for testing
30
+ class Tag < ActiveRecord::Base
31
+ self.primary_key = 'guid'
32
+ has_many :taggings
33
+ has_many :projects,
34
+ through: :taggings,
35
+ source: :taggable,
36
+ source_type: 'Project'
37
+ has_many :todolists,
38
+ through: :taggings,
39
+ source: :taggable,
40
+ source_type: 'Todolist'
41
+ has_many :todos,
42
+ through: :taggings,
43
+ source: :taggable,
44
+ source_type: 'Todo'
45
+
46
+ def taggables
47
+ projects + todolists + todos
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ ActiveRecord::Schema.define do
2
+ self.verbose = false
3
+
4
+ create_table :projects do |t|
5
+ t.string :name
6
+ t.string :description
7
+ t.integer :position
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :todolists do |t|
12
+ t.string :name
13
+ t.string :description
14
+ t.references :project
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :todos do |t|
19
+ t.string :action
20
+ t.string :location
21
+ t.text :notes
22
+ t.integer :duration_in_secs
23
+ t.integer :priority
24
+ t.references :todolist
25
+ t.timestamps
26
+ end
27
+
28
+ create_table :tags, id: false do |t|
29
+ t.primary_key :guid
30
+ t.string :name
31
+ end
32
+
33
+ create_table :taggings do |t|
34
+ t.references :tag
35
+ t.references :taggable, polymorphic: true
36
+ t.datetime :created_at
37
+ end
38
+ end
@@ -0,0 +1,57 @@
1
+ require 'simple_json_api'
2
+
3
+ # TagSerializer for testing
4
+ class TagSerializer < SimpleJsonApi::ResourceSerializer
5
+ serializes :tags, primary_key: :guid, model: Tag
6
+ attribute :guid
7
+ attribute :name
8
+
9
+ has_many :taggables, polymorphic: true
10
+ end
11
+
12
+ # TaggingSerializer for testing
13
+ class TaggingSerializer < SimpleJsonApi::ResourceSerializer
14
+ serializes :taggings
15
+ attribute :id
16
+ belongs_to :tag
17
+ belongs_to :taggable, polymorphic: true
18
+ end
19
+
20
+ # TodoSerializer for testing
21
+ class TodoSerializer < SimpleJsonApi::ResourceSerializer
22
+ serializes :todos, model: Todo
23
+ attribute :id
24
+ attribute :action
25
+ attribute :location
26
+ attribute :notes
27
+ has_many :tags
28
+ def href
29
+ "http://example.com/todos/#{_object.id}"
30
+ end
31
+ end
32
+
33
+ # TodolistSerializer for testing
34
+ class TodolistSerializer < SimpleJsonApi::ResourceSerializer
35
+ serializes :todolists, model: Todolist
36
+ attribute :id
37
+ attribute :description
38
+ has_many :todos
39
+ has_many :tags
40
+ def href
41
+ "http://example.com/todolists/#{_object.id}"
42
+ end
43
+ end
44
+
45
+ # ProjectSerializer for testing
46
+ class ProjectSerializer < SimpleJsonApi::ResourceSerializer
47
+ serializes :projects, model: Project
48
+ attribute :id
49
+ attribute :name, key: :project_name
50
+ attribute :description
51
+ attribute :position
52
+ has_one :todolist
53
+ has_many :tags
54
+ def href
55
+ "http://example.com/projects/#{_object.id}"
56
+ end
57
+ end
@@ -0,0 +1,33 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'bundler/setup'
5
+
6
+ require 'simplecov'
7
+ if ENV['COVERAGE']
8
+ SimpleCov.start do
9
+ add_filter '/test/'
10
+ end
11
+ SimpleCov.minimum_coverage 95
12
+ end
13
+
14
+ require 'minitest/autorun'
15
+ require 'minitest/reporters'
16
+ Minitest::Reporters.use!(
17
+ # Minitest::Reporters::DefaultReporter.new(color: true)
18
+ Minitest::Reporters::SpecReporter.new
19
+ )
20
+
21
+ require 'ap'
22
+ require 'simple_json_api'
23
+ require 'test_setup'
24
+ require 'diffy'
25
+
26
+ # Helper to highlight diffs between two json strings
27
+ # compare_json(actual_projects, expected_projects.to_json)
28
+ def compare_json(actual_json, expected_json)
29
+ actual_pretty = JSON.pretty_generate(JSON.parse(actual_json))
30
+ expected_pretty = JSON.pretty_generate(JSON.parse(expected_json))
31
+ diff = Diffy::Diff.new(actual_pretty, expected_pretty)
32
+ puts "\n#{diff}\n" unless diff.to_s.empty?
33
+ end
@@ -0,0 +1,19 @@
1
+ require 'rails'
2
+ require 'active_record'
3
+
4
+ ActiveRecord::Base.establish_connection(
5
+ adapter: 'sqlite3', database: ':memory:'
6
+ )
7
+ load File.dirname(__FILE__) + '/setup/schema.rb'
8
+
9
+ # dump the actual schema
10
+ # require 'active_record/schema_dumper'
11
+ # filename = File.join('test', 'tmp', 'schema.rb')
12
+ # File.open(filename, 'w:utf-8') do |file|
13
+ # ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
14
+ # end
15
+
16
+ require 'setup/models'
17
+ require 'setup/serializers'
18
+
19
+ load File.dirname(__FILE__) + '/setup/data.rb'
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended that you check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(version: 0) do
15
+
16
+ create_table "projects", force: true do |t|
17
+ t.string "name"
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ create_table "taggings", force: true do |t|
23
+ t.integer "tag_id"
24
+ t.integer "taggable_id"
25
+ t.string "taggable_type"
26
+ t.datetime "created_at"
27
+ end
28
+
29
+ create_table "tags", force: true do |t|
30
+ t.string "name"
31
+ end
32
+
33
+ create_table "todolists", force: true do |t|
34
+ t.string "description"
35
+ t.integer "project_id"
36
+ t.datetime "created_at"
37
+ t.datetime "updated_at"
38
+ end
39
+
40
+ create_table "todos", force: true do |t|
41
+ t.string "action"
42
+ t.integer "todolist_id"
43
+ t.datetime "created_at"
44
+ t.datetime "updated_at"
45
+ end
46
+
47
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ # SimpleJsonApi
4
+ module SimpleJsonApi
5
+ describe 'AssociationTest' do
6
+ it 'should create an Association object' do
7
+ association = SimpleJsonApi::Association.new(
8
+ 'project', :has_one, ProjectSerializer
9
+ )
10
+ association.name.must_equal 'project'
11
+ association.type.must_equal :has_one
12
+ association.serializer.must_equal ProjectSerializer
13
+ association.key.must_equal :project
14
+ refute association.polymorphic
15
+ end
16
+
17
+ it 'should create an Association for a polymorphic object' do
18
+ association = SimpleJsonApi::Association.new(
19
+ 'project', :has_many, ProjectSerializer, true
20
+ )
21
+ association.name.must_equal 'project'
22
+ association.type.must_equal :has_many
23
+ association.serializer.must_equal ProjectSerializer
24
+ association.key.must_equal :projects
25
+ assert association.polymorphic
26
+ end
27
+ end
28
+ end