Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature:lib] Add serialization support #63

Merged
merged 7 commits into from
May 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/arx.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'cgi'
require 'json'
require 'nokogiri'
require 'open-uri'
require 'happymapper'
Expand Down
26 changes: 25 additions & 1 deletion lib/arx/entities/author.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class Author
include HappyMapper
include Inspector

# The attributes of an arXiv paper's author.
ATTRIBUTES = %i[name affiliated? affiliations]

tag 'author'

# @!method name
Expand All @@ -23,6 +26,27 @@ def affiliated?
!affiliations.empty?
end

inspector :name, :affiliated?, :affiliations
# Serializes the {Author} object into a +Hash+.
#
# @return [Hash]
def to_h
Hash[*ATTRIBUTES.map {|_| [_, send(_)]}.flatten(1)]
end

# Serializes the {Author} object into a valid JSON hash.
#
# @return [Hash] The resulting JSON hash.
def as_json
JSON.parse to_json
end

# Serializes the {Author} object into a valid JSON string.
#
# @return [String] The resulting JSON string.
def to_json
to_h.to_json
end

inspector *ATTRIBUTES
end
end
26 changes: 25 additions & 1 deletion lib/arx/entities/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class Category
include HappyMapper
include Inspector

# The attributes of an arXiv paper's category.
ATTRIBUTES = %i[name full_name]

tag 'category'

# @!method name
Expand All @@ -19,6 +22,27 @@ def full_name
CATEGORIES[name]
end

inspector :name, :full_name
# Serializes the {Category} object into a +Hash+.
#
# @return [Hash]
def to_h
Hash[*ATTRIBUTES.map {|_| [_, send(_)]}.flatten(1)]
end

# Serializes the {Category} object into a valid JSON hash.
#
# @return [Hash] The resulting JSON hash.
def as_json
JSON.parse to_json
end

# Serializes the {Category} object into a valid JSON string.
#
# @return [String] The resulting JSON string.
def to_json
to_h.to_json
end

inspector *ATTRIBUTES
end
end
54 changes: 44 additions & 10 deletions lib/arx/entities/paper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ class Paper
include HappyMapper
include Inspector

# The attributes of an arXiv paper.
# @note {comment}, {journal}, {pdf_url} and {doi_url} may raise errors when called.
ATTRIBUTES = %i[
id url version revision?
title summary authors
primary_category categories
published_at updated_at
comment? comment
journal? journal
pdf? pdf_url
doi? doi_url
]

tag 'entry'

element :id, Cleaner, parser: :clean, tag: 'id'
Expand Down Expand Up @@ -159,15 +172,36 @@ def revision?
end
end

inspector *%i[
id url version revision?
title summary authors
primary_category categories
published_at updated_at
comment? comment
journal? journal
pdf? pdf_url
doi? doi_url
]
# Serializes the {Paper} object into a +Hash+.
#
# @param deep [Boolean] Whether to deep-serialize {Author} and {Category} objects.
# @return [Hash]
def to_h(deep = false)
Hash[*ATTRIBUTES.map {|_| [_, send(_)] rescue nil}.compact.flatten(1)].tap do |hash|
if deep
hash[:authors].map! &:to_h
hash[:categories].map! &:to_h
hash[:primary_category] = hash[:primary_category].to_h
end
end
end

# Serializes the {Paper} object into a valid JSON hash.
#
# @note Deep-serializes {Author} and {Category} objects.
# @return [Hash] The resulting JSON hash.
def as_json
JSON.parse to_json
end

# Serializes the {Paper} object into a valid JSON string.
#
# @note Deep-serializes {Author} and {Category} objects.
# @return [String] The resulting JSON string.
def to_json
to_h(true).to_json
end

inspector *ATTRIBUTES
end
end
49 changes: 49 additions & 0 deletions spec/arx/entities/author_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,53 @@
it { expect(authors[1].affiliations).to be_empty }
end
end
context '#to_h' do
context 'cond-mat/9609089' do
subject { authors[0].to_h }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a Symbol }
it { is_expected.to eq({affiliated?: true, affiliations: ["Philipps University Marburg, Germany"], name: "K. Bott"}) }
end
context '1105.5379' do
subject { authors[1].to_h }

it { is_expected.to eq({name: "Aapo Kyrola", affiliated?: false, affiliations: []}) }
end
context '1710.02185' do
subject { Arx.get('1710.02185').authors.first.to_h }

it { is_expected.to eq({name: "The LIGO Scientific Collaboration", affiliated?: false, affiliations: []}) }
end
end
context '#as_json' do
context 'cond-mat/9609089' do
subject { authors[0].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({'affiliated?'=>true, 'affiliations'=>["Philipps University Marburg, Germany"], 'name'=>"K. Bott"}) }
end
context '1105.5379' do
subject { authors[1].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({'name'=>"Aapo Kyrola", 'affiliated?'=>false, 'affiliations'=>[]}) }
end
end
context '#to_json' do
context 'cond-mat/9609089' do
subject { authors[0].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq "{\"name\":\"K. Bott\",\"affiliated?\":true,\"affiliations\":[\"Philipps University Marburg, Germany\"]}" }
end
context '1105.5379' do
subject { authors[1].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq "{\"name\":\"Aapo Kyrola\",\"affiliated?\":false,\"affiliations\":[]}" }
end
end
end
83 changes: 83 additions & 0 deletions spec/arx/entities/category_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,87 @@
it { expect(subject[2].full_name).to be_nil } # ACM classes
end
end
context '#to_h' do
context 'cond-mat/9609089' do
subject { categories[0].to_h }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a Symbol }
it { is_expected.to eq({full_name: "Condensed Matter", name: "cond-mat"}) }
end
context '1105.5379' do
subject { categories[1].to_h }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a Symbol }
it { is_expected.to eq({full_name: "Learning", name: "cs.LG"}) }
end
context '1710.02185' do
subject { Arx.get('1710.02185').primary_category.to_h }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a Symbol }
it { is_expected.to eq({full_name: "General Relativity and Quantum Cosmology", name: "gr-qc"}) }
end
end
context '#as_json' do
context 'cond-mat/9609089' do
subject { categories[0].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({"full_name"=>"Condensed Matter", "name"=>"cond-mat"}) }
end
context '1105.5379' do
subject { categories[1].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({"full_name"=>"Learning", "name"=>"cs.LG"}) }
end
context '1703.04834' do
context 'MSC' do
subject { Arx.get('1703.04834').categories[1].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({"full_name"=>nil, "name"=>"03D05"}) }
end
context 'ACM' do
subject { Arx.get('1703.04834').categories[2].as_json }

it { is_expected.to be_a Hash }
it { expect(subject.keys).to all be_a String }
it { is_expected.to eq({"full_name"=>nil, "name"=>"F.1.1; F.4.1"}) }
end
end
end
context '#to_json' do
context 'cond-mat/9609089' do
subject { categories[0].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq("{\"name\":\"cond-mat\",\"full_name\":\"Condensed Matter\"}") }
end
context '1105.5379' do
subject { categories[1].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq("{\"name\":\"cs.LG\",\"full_name\":\"Learning\"}") }
end
context '1703.04834' do
context 'MSC' do
subject { Arx.get('1703.04834').categories[1].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq("{\"name\":\"03D05\",\"full_name\":null}") }
end
context 'ACM' do
subject { Arx.get('1703.04834').categories[2].to_json }

it { is_expected.to be_a String }
it { is_expected.to eq("{\"name\":\"F.1.1; F.4.1\",\"full_name\":null}") }
end
end
end
end
Loading