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

"Splits parsable interface for ruby + Duration, Time, and Date Support" #1765

Merged
merged 25 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dac873b
"Splits parsable interface for ruby"
osose-e Jul 28, 2022
d5c755b
Time serialization/deserialization additions
osose-e Aug 10, 2022
6c99ca3
Update to Changelog Unreleased Additions & Changed
osose-e Aug 10, 2022
8681b2f
Protecting underlying duration obj
osose-e Aug 10, 2022
e2c8f59
Merge branch 'main' into osose-refiners-ruby-features
baywet Aug 10, 2022
e9c2fae
Adding unit tests
osose-e Aug 10, 2022
a9ec856
Merge branch 'osose-refiners-ruby-features' of https://github.com/mic…
osose-e Aug 10, 2022
4caf96c
Gemfile update
osose-e Aug 10, 2022
afec2e4
Updating require statements
osose-e Aug 10, 2022
ee09db2
Updating require statements
osose-e Aug 10, 2022
458ff7a
Serialization require updates
osose-e Aug 10, 2022
1f58fe7
Updating serialization require statments and tests
osose-e Aug 11, 2022
83d6b2a
Changing require statements to package references
osose-e Aug 11, 2022
43a1e5b
Changing more requires to pkg refs
osose-e Aug 11, 2022
8434abb
Fixing typo in a pkg ref
osose-e Aug 11, 2022
51822bf
Another pkg ref fix
osose-e Aug 11, 2022
4953ae3
Uninitialized constant resolution
osose-e Aug 11, 2022
707228f
Addressing the NameError from serialization builds
osose-e Aug 11, 2022
2783815
Used local pkg reference method
osose-e Aug 11, 2022
b3ea17b
More on local references
osose-e Aug 11, 2022
a3aa249
Original Gemfile restoration
osose-e Aug 11, 2022
355ef8e
- maps serialization methods for date types in ruby
baywet Aug 12, 2022
b22e43c
Merge branch 'main' into osose-refiners-ruby-features
baywet Aug 12, 2022
6958820
- bumps minor for kiota abstractions ruby
baywet Aug 12, 2022
d61a22e
- bumps minor for kiota serialization json
baywet Aug 12, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for no-content responses in python abstractions and http packages. [#1630](https://github.com/microsoft/kiota/issues/1459)
- Added support for vendor-specific content types in python. [#1631](https://github.com/microsoft/kiota/issues/1463)
- Simplified field deserializers for json in Python. [#1632](https://github.com/microsoft/kiota/issues/1492)
- Added native type support for Duration, Time Only, and Date Only in Ruby. [#1644](https://github.com/microsoft/kiota/issues/1644)
- Added a `--additional-data` argument to generate the AdditionalData properties [#1772](https://github.com/microsoft/kiota/issues/1772)

### Changed
Expand All @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed duplicate properties defined in base types from model serialization and deserialization methods and initialise property defaults in constructor. [#1737](https://github.com/microsoft/kiota/pull/1737)
- Fixed a bug where the generated code had incorrect casing within a method (Ruby). [#1672](https://github.com/microsoft/kiota/issues/1672)
- Fixed an issue where duplicate 'require' statements are generated for inner classes in the middle of the file (Ruby). [#1649](https://github.com/microsoft/kiota/issues/1649)
- Split parsable interface and additional property/data interface in Ruby. [#1654](https://github.com/microsoft/kiota/issues/1654)
- Changed format of datetimes in Go to be converted to ISO 8601 by default when place in path parameters(Go)

## [0.3.0] - 2022-07-08
Expand Down
4 changes: 3 additions & 1 deletion abstractions/ruby/microsoft_kiota_abstractions/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ gem 'rubocop', require: false

gem 'concurrent-ruby', '~> 1.1', '>= 1.1.9'

gem 'addressable', '~> 2.7', '>= 2.7.0'
gem 'addressable', '~> 2.7', '>= 2.7.0'

gem 'iso8601', '~> 0.13.0'
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
require_relative "microsoft_kiota_abstractions/response_handler"
require_relative "microsoft_kiota_abstractions/version"
require_relative "microsoft_kiota_abstractions/serialization/parsable"
require_relative "microsoft_kiota_abstractions/serialization/iso_duration"
require_relative "microsoft_kiota_abstractions/serialization/additional_data_holder"
require_relative "microsoft_kiota_abstractions/serialization/parse_node"
require_relative "microsoft_kiota_abstractions/serialization/parse_node_factory"
require_relative "microsoft_kiota_abstractions/serialization/parse_node_factory_registry"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module MicrosoftKiotaAbstractions
module AdditionalDataHolder
def additional_data
@additional_data ||= Hash.new
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# frozen_string_literal: true
require 'iso8601'

module MicrosoftKiotaAbstractions
# Wrapper Class for ISO8601::Duration
# Integer support for :years, :months, :weeks, :days, :hours, :minutes, :seconds
# Initialize with a hash of symbols to integers eg { :years => 3, :days => 4, seconds: => 2}
# or with an ISO8601 formated string eg "PT3H12M5S".
class ISODuration
attr_reader :years, :months, :weeks, :days, :hours, :minutes, :seconds

UNITS = { :years => 'Y',
:months => 'M',
:weeks => 'W',
:days => 'D',
:hours => 'H',
:minutes => 'M',
:seconds => 'S'}

CONVERSIONS = {
:ms_to_s => 1000,
:s_to_m => 60,
:m_to_h => 60,
:h_to_d => 24,
:d_to_w => 7,
:m_to_y => 12
}
def initialize(input)
if input.is_a? String
@duration_obj = ISO8601::Duration.new(input)
elsif input.is_a? Hash
@duration_obj = parse_hash(input)
else
raise StandardError, 'Must provide initialize ISODuration by providing a hash or an ISO8601-formatted string.'
end
update_member_variables
normalize
end

def string
input = { :seconds => @seconds, :minutes => @minutes, :hours => @hours,
:days => @days, :weeks => @weeks, :months => @months,
:years => @years }
iso_str = 'P'
UNITS.each do |unit, abrev|
iso_str += input[unit].to_s + abrev unless input[unit].zero?
iso_str += 'T' if unit == :days
end
iso_str = iso_str.strip
iso_str = iso_str.chomp('T') if (iso_str[-1]).eql? 'T'
iso_str
end

def normalize
if @seconds >= CONVERSIONS[:s_to_m]
@minutes += (@seconds / CONVERSIONS[:s_to_m]).floor
@seconds %= CONVERSIONS[:s_to_m]
end
if @minutes >= CONVERSIONS[:m_to_h]
@hours += (@minutes / CONVERSIONS[:m_to_h]).floor
@minutes %= CONVERSIONS[:m_to_h]
end
if @hours >= CONVERSIONS[:h_to_d]
@days += (@hours / CONVERSIONS[:h_to_d]).floor
@hours %= CONVERSIONS[:h_to_d]
end
if @days >= CONVERSIONS[:d_to_w] && @months == 0 && @years == 0
@weeks += (@days / CONVERSIONS[:d_to_w]).floor
@days %= CONVERSIONS[:d_to_w]
end
if @months > CONVERSIONS[:m_to_y]
@years += (@months / CONVERSIONS[:m_to_y]).floor
@months %= CONVERSIONS[:m_to_y]
end
end

def seconds=(value)
input = { :seconds => value, :minutes => @minutes, :hours => @hours,
:days => @days, :weeks => @weeks, :months => @months,
:years => @years }
@duration_obj = parse_hash(input)
@seconds = value
normalize
end

def minutes=(value)
input = { :seconds => @seconds, :minutes => value, :hours => @hours,
:days => @days, :weeks => @weeks, :months => @months,
:years => @years }
@duration_obj = parse_hash(input)
@minutes = value
normalize
end

def hours=(value)
input = { :seconds => @seconds, :minutes => @minutes, :hours => value,
:days => @days, :weeks => @weeks, :months => @months,
:years => @years }
@duration_obj = parse_hash(input)
@hours = value
normalize
end

def days=(value)
input = { :seconds => @seconds, :minutes => @minutes, :hours => @hours,
:days => value, :weeks => @weeks, :months => @months,
:years => @years }
@duration_obj = parse_hash(input)
@days = value
normalize
end

def weeks=(value)
input = { :seconds => @seconds, :minutes => @minutes, :hours => @hours,
:days => @days, :weeks => value, :months => @months,
:years => @years }
@duration_obj = parse_hash(input)
@weeks = value
normalize
end

def months=(value)
input = { :seconds => @seconds, :minutes => @minutes, :hours => @hours,
:days => @days, :weeks => @weeks, :months => value,
:years => @years }
@duration_obj = parse_hash(input)
@months = value
normalize
end

def years=(value)
input = { :seconds => @seconds, :minutes => @minutes, :hours => @hours,
:days => @days, :weeks => @weeks, :months => @months,
:years => value }
@duration_obj = parse_hash(input)
@years = value
normalize
end

def abs
@duration_obj = @duration_obj.abs
update_member_variables
return self
end

def +(other)
new_obj = self.duration_obj + other.duration_obj
MicrosoftKiotaAbstractions::ISODuration.new(dur_obj_to_hash(new_obj))
end

def -(other)
new_obj = self.duration_obj - other.duration_obj
MicrosoftKiotaAbstractions::ISODuration.new(dur_obj_to_hash(new_obj))
end

def ==(other)
@duration_obj == other.duration_obj
end

def -@
@duration_obj = -@duration_obj
update_member_variables
end

def eql?(other)
@duration_obj == other.duration_obj
end

protected

attr_accessor :duration_obj

def parse_hash(input)
iso_str = 'P'
input.each do |keys, values|
raise StandardError, "The key #{keys} is not recognized" unless UNITS.key?(keys)
end
UNITS.each do |unit, abrev|
iso_str += input[unit].to_s + abrev if input.key?(unit) && !input[unit].zero?
iso_str += 'T' if unit == :days
end
iso_str = iso_str.strip
iso_str = iso_str.chomp('T') if (iso_str[-1]).eql? 'T'
ISO8601::Duration.new(iso_str)
end

def update_member_variables
@seconds = @duration_obj.seconds.nil? ? 0 : ((@duration_obj.seconds.to_s).split('S')[0]).to_i
@minutes = @duration_obj.minutes.nil? ? 0 : ((@duration_obj.minutes.to_s).split('H')[0]).to_i
@hours = @duration_obj.hours.nil? ? 0 : ((@duration_obj.hours.to_s).split('H')[0]).to_i
@days = @duration_obj.days.nil? ? 0 : ((@duration_obj.days.to_s).split('D')[0]).to_i
@weeks = @duration_obj.weeks.nil? ? 0 : ((@duration_obj.weeks.to_s).split('W')[0]).to_i
@months = @duration_obj.months.nil? ? 0 : ((@duration_obj.months.to_s).split('M')[0]).to_i
@years = @duration_obj.years.nil? ? 0 : ((@duration_obj.years.to_s).split('Y')[0]).to_i
end

def dur_obj_to_hash(dur_obj)
result_hash = {}
result_hash[:seconds] = dur_obj.seconds.nil? ? 0 : ((dur_obj.seconds.to_s).split('S')[0]).to_i
result_hash[:minutes] = dur_obj.minutes.nil? ? 0 : ((dur_obj.minutes.to_s).split('H')[0]).to_i
result_hash[:hours] = dur_obj.hours.nil? ? 0 : ((dur_obj.hours.to_s).split('H')[0]).to_i
result_hash[:days] = dur_obj.days.nil? ? 0 : ((dur_obj.days.to_s).split('D')[0]).to_i
result_hash[:weeks] = dur_obj.weeks.nil? ? 0 : ((dur_obj.weeks.to_s).split('W')[0]).to_i
result_hash[:months] = dur_obj.months.nil? ? 0 : ((dur_obj.months.to_s).split('M')[0]).to_i
result_hash[:years] = dur_obj.years.nil? ? 0 : ((dur_obj.years.to_s).split('Y')[0]).to_i
result_hash
end
end
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
module MicrosoftKiotaAbstractions
module Parsable
def additional_data
@additional_data ||= Hash.new
end

def get_field_deserializers
raise NotImplementedError.new
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ def get_date_value()
raise NotImplementedError.new
end

def get_time_value()
raise NotImplementedError.new
end

def get_date_time_value()
raise NotImplementedError.new
end

def get_duration_value()
raise NotImplementedError.new
end

def get_collection_of_primitive_values()
raise NotImplementedError.new
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ def write_guid_value(key, value)
def write_date_value(key, value)
raise NotImplementedError.new
end

def write_time_value(key, value)
raise NotImplementedError.new
end

def write_date_time_value(key, value)
raise NotImplementedError.new
end

def write_duration_value(key, value)
raise NotImplementedError.new
end

def write_collection_of_primitive_values(key, value)
raise NotImplementedError.new
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module MicrosoftKiotaAbstractions
VERSION = "0.1.11"
VERSION = "0.2.0"
end
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']
spec.add_dependency 'concurrent-ruby', '~> 1.1', '>= 1.1.9'
spec.add_dependency 'addressable', '~> 2.7', '>= 2.7.0'
spec.add_dependency 'iso8601', '~> 0.13.0'
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'uri'
# frozen_string_literal: true
require 'uri'
require 'microsoft_kiota_abstractions'


RSpec.describe MicrosoftKiotaAbstractions do
it "has a version number" do
Expand Down Expand Up @@ -54,4 +56,39 @@
request_obj.query_parameters["q1"] = "option1"
expect(request_obj.uri).to eq(URI("https://www.bing.com/search?q1=option1"))
end

it "initializes a duration with ISO-formatted string or hash" do
time1 = MicrosoftKiotaAbstractions::ISODuration.new("P2Y1MT2H")
time2 = MicrosoftKiotaAbstractions::ISODuration.new({ :years => 2, :months => 1, :hours => 2 } )
expect(time1).to eq(time2)
end

it "fails on malformed string inputs" do
expect { MicrosoftKiotaAbstractions::ISODuration.new("P2Y1M3WT2H") }.to raise_error ISO8601::Errors::UnknownPattern
end

it "fails on malformed hash inputs" do
expect { MicrosoftKiotaAbstractions::ISODuration.new({ :laughter => 2, :months => 1, :hours => 2 }) }.to raise_error('The key laughter is not recognized')
end

it "handles addition" do
time1 = MicrosoftKiotaAbstractions::ISODuration.new("P2Y1MT2H")
time2 = MicrosoftKiotaAbstractions::ISODuration.new({ :years => 2, :months => 1, :hours => 2 } )
time3 = time1 + time2
expect(time3.string).to eq(MicrosoftKiotaAbstractions::ISODuration.new("P4Y2MT4H").string)
end

it "handles subtraction" do
time1 = MicrosoftKiotaAbstractions::ISODuration.new("P4Y2MT2H")
time2 = MicrosoftKiotaAbstractions::ISODuration.new({ :years => 1, :months => 1, :hours => 2 } )
time3 = time1 - time2

expect(time3.string).to eq(MicrosoftKiotaAbstractions::ISODuration.new("P3Y1M").string)
end

it "handles equality comparisons" do
time1 = MicrosoftKiotaAbstractions::ISODuration.new("P4Y2MT2H")
time2 = MicrosoftKiotaAbstractions::ISODuration.new({ :years => 4, :months => 2, :hours => 2 } )
expect(time1).to eq(time2)
end
end
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require "microsoft_kiota_abstractions"

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status"
Expand Down
Loading