Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ExpressionToCode library for unit test expression-based asserts.
Added Xml(De)Serializers based on .Net framework XmlSerializer. Updated Subscriber and SubscriberList entity definitions to use Xml attributes rather than the RestSharp attributes. Added dedicated Deserialization unit tests for SubscriberList.
- Loading branch information
dan
committed
Sep 8, 2011
1 parent
2778b92
commit 3edf806
Showing
11 changed files
with
371 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,75 +1,113 @@ | |||
namespace Spreedly.Net.Entities | namespace Spreedly.Net.Entities | ||
{ | { | ||
using System; | using System; | ||
using RestSharp.Serializers; | using System.Xml.Serialization; | ||
using Xml; | |||
|
|
||
[SerializeAs(NameStyle = NameStyle.LowerCase)] | [XmlRoot(ElementName = "subscriber")] | ||
public class Subscriber | public class Subscriber | ||
{ | { | ||
|
|
||
public bool? Active { get; set; } | [XmlElement(ElementName = "active", IsNullable = true)] | ||
[SerializeAs(Name = "active-until")] | public SerializableNullable<bool> Active { get; set; } | ||
public DateTime? ActiveUntil { get; set; } |
|
||
[SerializeAs(Name = "billing-first-name")] | [XmlElement(ElementName = "active-until", IsNullable = true)] | ||
public SerializableNullable<DateTime> ActiveUntil { get; set; } | |||
|
|||
[XmlElement(ElementName = "billing-first-name")] | |||
public string BillingFirstName { get; set; } | public string BillingFirstName { get; set; } | ||
[SerializeAs(Name = "billing-last-name")] |
|
||
[XmlElement(ElementName = "billing-last-name")] | |||
public string BillingLastName { get; set; } | public string BillingLastName { get; set; } | ||
[SerializeAs(Name = "card-expires-before-next-auto-renew")] |
|
||
public bool? CardExpiresBeforeNextAutoRenew { get; set; } | [XmlElement(ElementName = "card-expires-before-next-auto-renew", IsNullable = true)] | ||
[SerializeAs(Name = "created-at")] | public SerializableNullable<bool> CardExpiresBeforeNextAutoRenew { get; set; } | ||
public DateTime? CreatedAt { get; set; } |
|
||
[SerializeAs(Name = "customer-id")] | [XmlElement(ElementName = "created-at", IsNullable = true)] | ||
public SerializableNullable<DateTime> CreatedAt { get; set; } | |||
|
|||
[XmlElement(ElementName = "customer-id")] | |||
public string CustomerId { get; set; } | public string CustomerId { get; set; } | ||
[SerializeAs(Name = "eligible-for-free-trial")] |
|
||
public bool? EligibleForFreeTrial { get; set; } | [XmlElement(ElementName = "eligible-for-free-trial", IsNullable = true)] | ||
public SerializableNullable<bool> EligibleForFreeTrial { get; set; } | |||
|
|||
[XmlElement(ElementName = "email")] | |||
public string Email { get; set; } | public string Email { get; set; } | ||
[SerializeAs(Name = "feature-level")] |
|
||
[XmlElement(ElementName = "feature-level")] | |||
public string FeatureLevel { get; set; } | public string FeatureLevel { get; set; } | ||
[SerializeAs(Name = "lifetime-subscription")] |
|
||
public bool? LifetimeSubscription { get; set; } | [XmlElement(ElementName = "lifetime-subscription", IsNullable = true)] | ||
[SerializeAs(Name = "on-trial")] | public SerializableNullable<bool> LifetimeSubscription { get; set; } | ||
public bool? OnTrial { get; set; } |
|
||
[SerializeAs(Name = "on-gift")] | [XmlElement(ElementName = "on-trial", IsNullable = true)] | ||
public bool? OnGift { get; set; } | public SerializableNullable<bool> OnTrial { get; set; } | ||
[SerializeAs(Name = "on-metered")] |
|
||
public bool? OnMetered { get; set; } | [XmlElement(ElementName = "on-gift", IsNullable = true)] | ||
public bool? Recurring { get; set; } | public SerializableNullable<bool> OnGift { get; set; } | ||
[SerializeAs(Name = "screen-name")] |
|
||
[XmlElement(ElementName = "on-metered")] | |||
public SerializableNullable<bool> OnMetered { get; set; } | |||
|
|||
[XmlElement(ElementName = "recurring", IsNullable = true)] | |||
public SerializableNullable<bool> Recurring { get; set; } | |||
|
|||
[XmlElement(ElementName = "screen-name")] | |||
public string ScreenName { get; set; } | public string ScreenName { get; set; } | ||
[SerializeAs(Name = "store-credit")] |
|
||
public decimal? StoreCredit { get; set; } | [XmlElement(ElementName = "store-credit")] | ||
[SerializeAs(Name = "store-credit-currency-code")] | public SerializableNullable<decimal> StoreCredit { get; set; } | ||
|
|||
[XmlElement(ElementName = "store-credit-currency-code")] | |||
public string StoreCreditCurrencyCode { get; set; } | public string StoreCreditCurrencyCode { get; set; } | ||
[SerializeAs(Name = "subscription-plan-name")] |
|
||
[XmlElement(ElementName = "subscription-plan-name")] | |||
public string SubscriptionPlanName { get; set; } | public string SubscriptionPlanName { get; set; } | ||
|
|||
[XmlElement(ElementName = "token")] | |||
public string Token { get; set; } | public string Token { get; set; } | ||
[SerializeAs(Name = "updated-at")] |
|
||
public DateTime? UpdatedAt { get; set; } | [XmlElement(ElementName = "updated-at", IsNullable = true)] | ||
[SerializeAs(Name = "grace-until")] | public SerializableNullable<DateTime> UpdatedAt { get; set; } | ||
public DateTime? GraceUntil { get; set; } |
|
||
[SerializeAs(Name = "in-grace-period")] | [XmlElement(ElementName = "grace-until", IsNullable = true)] | ||
public bool? InGracePeriod { get; set; } | public SerializableNullable<DateTime> GraceUntil { get; set; } | ||
[SerializeAs(Name = "ready-to-renew")] |
|
||
public bool? ReadyToRenew { get; set; } | [XmlElement(ElementName = "in-grace-period", IsNullable = true)] | ||
[SerializeAs(Name = "ready-to-renew-since")] | public SerializableNullable<bool> InGracePeriod { get; set; } | ||
public DateTime? ReadyToRenewSince { get; set; } |
|
||
[SerializeAs(Name = "payment-account-on-file")] | [XmlElement(ElementName = "ready-to-renew", IsNullable = true)] | ||
public bool? PaymentAccountOnFile { get; set; } | public SerializableNullable<bool> ReadyToRenew { get; set; } | ||
[SerializeAs(Name = "payment-account-display")] |
|
||
public bool? PaymentAccountDisplay { get; set; } | [XmlElement(ElementName = "ready-to-renew-since", IsNullable = true)] | ||
[SerializeAs(Name = "billing-address1")] | public SerializableNullable<DateTime> ReadyToRenewSince { get; set; } | ||
|
|||
[XmlElement(ElementName = "payment-account-on-file", IsNullable = true)] | |||
public SerializableNullable<bool> PaymentAccountOnFile { get; set; } | |||
|
|||
[XmlElement(ElementName = "payment-account-display", IsNullable = true)] | |||
public string PaymentAccountDisplay { get; set; } | |||
|
|||
[XmlElement(ElementName = "billing-address1")] | |||
public string BillingAddress1 { get; set; } | public string BillingAddress1 { get; set; } | ||
[SerializeAs(Name = "billing-city")] |
|
||
[XmlElement(ElementName = "billing-city")] | |||
public string BillingCity { get; set; } | public string BillingCity { get; set; } | ||
[SerializeAs(Name = "billing-state")] |
|
||
[XmlElement(ElementName = "billing-state")] | |||
public string BillingState { get; set; } | public string BillingState { get; set; } | ||
[SerializeAs(Name = "billing-zip")] |
|
||
[XmlElement(ElementName = "billing-zip")] | |||
public string BillingZip { get; set; } | public string BillingZip { get; set; } | ||
[SerializeAs(Name = "billing-country")] |
|
||
[XmlElement(ElementName = "billing-country")] | |||
public string BillingCountry { get; set; } | public string BillingCountry { get; set; } | ||
[SerializeAs(Name = "billing-phone-number")] |
|
||
[XmlElement(ElementName = "billing-phone-number")] | |||
public string BillingPhoneNumber { get; set; } | public string BillingPhoneNumber { get; set; } | ||
[SerializeAs(Name = "payment-method")] |
|
||
[XmlElement(ElementName = "payment-method")] | |||
public CreditCard PaymentMethod { get; set; } | public CreditCard PaymentMethod { get; set; } | ||
} | } | ||
} | } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,31 @@ | |||
namespace Spreedly.Net.Xml | |||
{ | |||
using System.IO; | |||
using System.Xml; | |||
using System.Xml.Serialization; | |||
using RestSharp; | |||
using RestSharp.Deserializers; | |||
|
|||
public class FrameworkDeserializer: IDeserializer | |||
{ | |||
public T Deserialize<T>(RestResponse response) where T : new() | |||
{ | |||
if (response == null || response.Content == null) | |||
return default(T); | |||
|
|||
XmlDocument doc; | |||
return Deserialize<T>(XmlReader.Create(new StringReader(response.Content))); | |||
} | |||
|
|||
private T Deserialize<T>(XmlReader contentReader) | |||
{ | |||
var serializer = new XmlSerializer(typeof (T)); | |||
return (T)serializer.Deserialize(contentReader); | |||
} | |||
|
|||
public string RootElement { get; set; } | |||
public string Namespace { get; set; } | |||
public string DateFormat { get; set; } | |||
} | |||
|
|||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,46 @@ | |||
namespace Spreedly.Net.Xml | |||
{ | |||
using System.IO; | |||
using System.Text; | |||
using System.Xml.Serialization; | |||
using RestSharp.Serializers; | |||
|
|||
public class FrameworkSerializer: ISerializer | |||
{ | |||
public string Serialize(object obj) | |||
{ | |||
var ns = new XmlSerializerNamespaces(); | |||
ns.Add(string.Empty, this.Namespace); | |||
var serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); | |||
var writer = new EncodingStringWriter(this.Encoding); | |||
serializer.Serialize(writer, obj, ns); | |||
|
|||
return writer.ToString(); | |||
} | |||
|
|||
public Encoding Encoding { get; set; } | |||
public string RootElement { get; set; } | |||
public string Namespace { get; set; } | |||
public string DateFormat { get; set; } | |||
public string ContentType { get; set; } | |||
|
|||
|
|||
private class EncodingStringWriter : StringWriter | |||
{ | |||
private readonly Encoding encoding; | |||
|
|||
public EncodingStringWriter(Encoding encoding) | |||
{ | |||
this.encoding = encoding; | |||
} | |||
|
|||
public override Encoding Encoding | |||
{ | |||
get | |||
{ | |||
return this.encoding; | |||
} | |||
} | |||
} | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,88 @@ | |||
namespace Spreedly.Net.Xml | |||
{ | |||
using System; | |||
using System.ComponentModel; | |||
using System.Xml; | |||
using System.Xml.Schema; | |||
using System.Xml.Serialization; | |||
|
|||
public struct SerializableNullable<T> : IXmlSerializable, IEquatable<SerializableNullable<T>> where T : struct | |||
{ | |||
private T value; | |||
private bool hasValue; | |||
|
|||
private SerializableNullable(T value) | |||
{ | |||
hasValue = true; | |||
this.value = value; | |||
} | |||
|
|||
public bool HasValue | |||
{ | |||
get { return hasValue; } | |||
} | |||
|
|||
public T Value | |||
{ | |||
get { return value; } | |||
} | |||
|
|||
XmlSchema IXmlSerializable.GetSchema() | |||
{ | |||
return null; | |||
} | |||
|
|||
void IXmlSerializable.ReadXml(XmlReader reader) | |||
{ | |||
if (reader.GetAttribute("nil") == "true") | |||
{ | |||
ReadNullValue(); | |||
return; | |||
} | |||
ReadNonNullValue(reader); | |||
} | |||
|
|||
void IXmlSerializable.WriteXml(XmlWriter writer) | |||
{ | |||
if(HasValue) | |||
writer.WriteValue(value); | |||
else | |||
{ | |||
writer.WriteAttributeString("nil", string.Empty, "true"); | |||
writer.WriteValue(string.Empty); | |||
} | |||
} | |||
|
|||
private void ReadNullValue() | |||
{ | |||
hasValue = false; | |||
} | |||
|
|||
private void ReadNonNullValue(XmlReader reader) | |||
{ | |||
reader.ReadStartElement(); | |||
var s = reader.ReadString(); | |||
value = GetValue(s); | |||
reader.ReadEndElement(); | |||
hasValue = true; | |||
} | |||
|
|||
private T GetValue(string readValue) | |||
{ | |||
var descriptor = TypeDescriptor.GetConverter(typeof (T)); | |||
if (descriptor.CanConvertFrom(typeof(string))) | |||
return (T)descriptor.ConvertFromInvariantString(readValue); | |||
return default(T); | |||
} | |||
|
|||
public static implicit operator SerializableNullable<T>(T value) | |||
{ | |||
return new SerializableNullable<T>(value); | |||
} | |||
|
|||
public bool Equals(SerializableNullable<T> other) | |||
{ | |||
return HasValue == other.HasValue && Value.Equals(other.Value); | |||
} | |||
} | |||
} |
Oops, something went wrong.