summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth.Test/Messaging/Reflection/MessagePartTests.cs
blob: 90ccca47c0a97c59e4acecc7a6ee7045441a7d90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//-----------------------------------------------------------------------
// <copyright file="MessagePartTests.cs" company="Andrew Arnott">
//     Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOAuth.Test.Messaging.Reflection {
	using System;
	using System.Linq;
	using System.Reflection;
	using DotNetOAuth.Messaging;
	using DotNetOAuth.Messaging.Reflection;
	using DotNetOAuth.Test.Mocks;
	using Microsoft.VisualStudio.TestTools.UnitTesting;

	[TestClass]
	public class MessagePartTests : MessagingTestBase {
		[TestMethod, ExpectedException(typeof(ArgumentException))]
		public void OptionalNonNullableStruct() {
			this.ParameterizedMessageTypeTest(typeof(MessageWithNonNullableOptionalStruct));
		}

		[TestMethod]
		public void RequiredNonNullableStruct() {
			this.ParameterizedMessageTypeTest(typeof(MessageWithNonNullableRequiredStruct));
		}

		[TestMethod]
		public void OptionalNullableStruct() {
			this.ParameterizedMessageTypeTest(typeof(MessageWithNullableOptionalStruct));
		}

		[TestMethod]
		public void RequiredNullableStruct() {
			this.ParameterizedMessageTypeTest(typeof(MessageWithNullableRequiredStruct));
		}

		[TestMethod, ExpectedException(typeof(ArgumentNullException))]
		public void CtorNullMember() {
			new MessagePart(null, new MessagePartAttribute());
		}

		[TestMethod, ExpectedException(typeof(ArgumentNullException))]
		public void CtorNullAttribute() {
			PropertyInfo field = typeof(MessageWithNullableOptionalStruct).GetProperty("OptionalInt", BindingFlags.NonPublic | BindingFlags.Instance);
			new MessagePart(field, null);
		}

		[TestMethod]
		public void SetValue() {
			var message = new MessageWithNonNullableRequiredStruct();
			MessagePart part = this.ParameterizedMessageTypeTest(message.GetType());
			part.SetValue(message, "5");
			Assert.AreEqual(5, message.OptionalInt);
		}

		[TestMethod]
		public void GetValue() {
			var message = new MessageWithNonNullableRequiredStruct();
			message.OptionalInt = 8;
			MessagePart part = this.ParameterizedMessageTypeTest(message.GetType());
			Assert.AreEqual("8", part.GetValue(message));
		}

		[TestMethod, ExpectedException(typeof(ArgumentException))]
		public void NonFieldOrPropertyMember() {
			MemberInfo method = typeof(MessageWithNullableOptionalStruct).GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance);
			new MessagePart(method, new MessagePartAttribute());
		}

		private MessagePart ParameterizedMessageTypeTest(Type messageType) {
			PropertyInfo field = messageType.GetProperty("OptionalInt", BindingFlags.NonPublic | BindingFlags.Instance);
			MessagePartAttribute attribute = field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType<MessagePartAttribute>().Single();
			return new MessagePart(field, attribute);
		}

		private class MessageWithNonNullableOptionalStruct : TestMessage {
			// Optional structs like int must be nullable for Optional to make sense.
			[MessagePart(IsRequired = false)]
			internal int OptionalInt { get; set; }
		}

		private class MessageWithNonNullableRequiredStruct : TestMessage {
			// This should work because a required field will always have a value so it
			// need not be nullable.
			[MessagePart(IsRequired = true)]
			internal int OptionalInt { get; set; }
		}

		private class MessageWithNullableOptionalStruct : TestMessage {
			// Optional structs like int must be nullable for Optional to make sense.
			[MessagePart(IsRequired = false)]
			internal int? OptionalInt { get; set; }
		}

		private class MessageWithNullableRequiredStruct : TestMessage {
			[MessagePart(IsRequired = true)]
			private int? OptionalInt { get; set; }
		}
	}
}