From 5beaa735f846d52e2a06a8e05d14bb28219ae58b Mon Sep 17 00:00:00 2001 From: Calin Date: Mon, 23 Jun 2014 11:47:25 +0300 Subject: [PATCH 1/7] fixes failing spec --- Refit-Tests/RestService.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Refit-Tests/RestService.cs b/Refit-Tests/RestService.cs index da8bee695..ec61d33a2 100644 --- a/Refit-Tests/RestService.cs +++ b/Refit-Tests/RestService.cs @@ -66,7 +66,7 @@ public void HitTheGitHubUserAPI() } [Test] - public void ShouldRetHttpResponseMessage() + public void ShouldRetHttpResponseMessage() { var fixture = RestService.For("https://api.github.com"); var result = fixture.GetIndex(); @@ -82,10 +82,28 @@ public void PostToRequestBin() var fixture = RestService.For("http://requestb.in/"); var result = fixture.Post(); - result.Wait(); + try + { + result.Wait(); + } + catch (AggregateException ae) + { + ae.Handle( + x => + { + if (x is HttpRequestException) + { + // we should be good but maybe a 404 occurred + return true; + } + + // other exception types might be valid failures + return false; + }); + } } - interface IRequestBin + public interface IRequestBin { [Post("/1h3a5jm1")] Task Post(); From 3ca9a3d6cf8daf75ce7d1bbabc2787f0955e81dd Mon Sep 17 00:00:00 2001 From: Calin Date: Mon, 23 Jun 2014 11:47:55 +0300 Subject: [PATCH 2/7] removes unused usings --- Refit-Tests/RestService.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Refit-Tests/RestService.cs b/Refit-Tests/RestService.cs index ec61d33a2..74fb33480 100644 --- a/Refit-Tests/RestService.cs +++ b/Refit-Tests/RestService.cs @@ -1,11 +1,8 @@ using System; using System.Net.Http; -using System.Collections.Generic; -using System.Linq; -using Castle.DynamicProxy; + using NUnit.Framework; using System.Threading.Tasks; -using System.Threading; namespace Refit.Tests { @@ -56,7 +53,7 @@ public interface IGitHubApi public class RestServiceIntegrationTests { [Test] - public void HitTheGitHubUserAPI() + public void HitTheGitHubUserApi() { var fixture = RestService.For("https://api.github.com"); var result = fixture.GetUser("octocat"); From f200b90a0bbcc710573dd880c669f72daf085d5e Mon Sep 17 00:00:00 2001 From: Calin Date: Mon, 23 Jun 2014 20:22:59 +0300 Subject: [PATCH 3/7] buildTaskFuncForMethod now takes into consideration the client absolute path --- Refit-Tests/RequestBuilder.cs | 85 +++++++++++++++++++-------- Refit-Tests/RestService.cs | 26 ++++++++ Refit/RequestBuilder.cs | 2 +- Refit/RequestBuilderImplementation.cs | 7 +-- 4 files changed, 92 insertions(+), 28 deletions(-) diff --git a/Refit-Tests/RequestBuilder.cs b/Refit-Tests/RequestBuilder.cs index b2c2bbea2..876d4d00e 100644 --- a/Refit-Tests/RequestBuilder.cs +++ b/Refit-Tests/RequestBuilder.cs @@ -2,14 +2,9 @@ using System.Net.Http; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; -using System.Text.RegularExpressions; +using System.Net; using NUnit.Framework; -using System.Text; -using Newtonsoft.Json; -using System.IO; -using System.Web; using System.Threading; namespace Refit.Tests @@ -19,7 +14,7 @@ public interface IRestMethodInfoTests { [Get("@)!@_!($_!@($\\\\|||::::")] Task GarbagePath(); - + [Get("/foo/bar/{id}")] Task FetchSomeStuffMissingParameters(); @@ -34,7 +29,7 @@ public interface IRestMethodInfoTests [Get("/foo/bar/{id}")] Task FetchSomeStuffWithAlias([AliasAs("id")] int anId); - + [Get("/foo/bar/{id}")] IObservable FetchSomeStuffWithBody([AliasAs("id")] int anId, [Body] Dictionary theData); @@ -60,10 +55,13 @@ public void GarbagePathsShouldThrow() { bool shouldDie = true; - try { + try + { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "GarbagePath")); - } catch (ArgumentException) { + } + catch (ArgumentException) + { shouldDie = false; } @@ -75,10 +73,13 @@ public void MissingParametersShouldBlowUp() { bool shouldDie = true; - try { + try + { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "FetchSomeStuffMissingParameters")); - } catch (ArgumentException) { + } + catch (ArgumentException) + { shouldDie = false; } @@ -184,10 +185,13 @@ public void SyncMethodsShouldThrow() { bool shouldDie = true; - try { + try + { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "AsyncOnlyBuddy")); - } catch (ArgumentException) { + } + catch (ArgumentException) + { shouldDie = false; } @@ -218,7 +222,7 @@ public interface IDummyHttpApi [Get("/foo/bar/{id}")] [Headers("Api-Version: ")] Task FetchSomeStuffWithEmptyHardcodedHeader(int id); - + [Get("/foo/bar/{id}")] [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==")] Task FetchSomeStuffWithDynamicHeader(int id, [Header("Authorization")] string authorization); @@ -226,9 +230,23 @@ public interface IDummyHttpApi [Get("/foo/bar/{id}")] Task FetchSomeStuffWithCustomHeader(int id, [Header("X-Emoji")] string custom); + [Get("/some")] + Task FetchSomeStuffWithoutFullPath(); + string SomeOtherMethod(); } + public class TestHttpMessageHandler : HttpMessageHandler + { + public HttpRequestMessage RequestMessage { get; private set; } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + RequestMessage = request; + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("test") }); + } + } + [TestFixture] public class RequestBuilderTests { @@ -245,25 +263,33 @@ public void MethodsThatDontHaveAnHttpMethodShouldFail() "FetchSomeStuff", }; - foreach (var v in failureMethods) { + foreach (var v in failureMethods) + { bool shouldDie = true; - try { + try + { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); - } catch (Exception ex) { + } + catch (Exception ex) + { shouldDie = false; } Assert.IsFalse(shouldDie); } - foreach (var v in successMethods) { + foreach (var v in successMethods) + { bool shouldDie = false; - try { + try + { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); - } catch (Exception ex) { + } + catch (Exception ex) + { shouldDie = true; } @@ -281,7 +307,7 @@ public void HardcodedQueryParamShouldBeInUrl() var uri = new Uri(new Uri("http://api"), output.RequestUri); Assert.AreEqual("/foo/bar/6?baz=bamf", uri.PathAndQuery); } - + [Test] public void ParameterizedQueryParamsShouldBeInUrl() { @@ -342,7 +368,7 @@ public void DynamicHeaderShouldBeInHeaders() } [Test] - public void CustomDynamicHeaderShouldBeInHeaders() + public void CustomDynamicHeaderShouldBeInHeaders() { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithCustomHeader"); @@ -372,5 +398,18 @@ public void NullDynamicHeaderShouldNotBeInHeaders() Assert.IsNull(output.Headers.Authorization, "Headers include Authorization header"); } + + [Test] + public void HttpClientPathShouldBePrefixedToTheRequestUri() + { + var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); + var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithoutFullPath"); + var testHttpMessageHandler = new TestHttpMessageHandler(); + + var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]); + task.Wait(); + + Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/some"); + } } } \ No newline at end of file diff --git a/Refit-Tests/RestService.cs b/Refit-Tests/RestService.cs index 74fb33480..130a563e2 100644 --- a/Refit-Tests/RestService.cs +++ b/Refit-Tests/RestService.cs @@ -6,6 +6,8 @@ namespace Refit.Tests { + using System.Security.Cryptography.X509Certificates; + public class User { public string login { get; set; } @@ -49,6 +51,20 @@ public interface IGitHubApi Task GetIndex(); } + public class RootObject + { + public string _id { get; set; } + public string _rev { get; set; } + public string name { get; set; } + } + + [Headers("User-Agent: Refit Integration Tests")] + public interface INpmJs + { + [Get("/congruence")] + Task GetCongruence(); + } + [TestFixture] public class RestServiceIntegrationTests { @@ -73,6 +89,16 @@ public void ShouldRetHttpResponseMessage() Assert.IsTrue(result.Result.IsSuccessStatusCode); } + [Test] + public void HitTheNpmJs() + { + var fixture = RestService.For("https://registry.npmjs.us/public"); + var result = fixture.GetCongruence(); + + result.Wait(); + Assert.AreEqual("congruence", result.Result._id); + } + [Test] public void PostToRequestBin() { diff --git a/Refit/RequestBuilder.cs b/Refit/RequestBuilder.cs index 08d80b8f3..ef70bdf6c 100644 --- a/Refit/RequestBuilder.cs +++ b/Refit/RequestBuilder.cs @@ -7,7 +7,7 @@ namespace Refit public interface IRequestBuilder { IEnumerable InterfaceHttpMethods { get; } - Func BuildRequestFactoryForMethod(string methodName); + Func BuildRequestFactoryForMethod(string methodName, string basePath = ""); Func BuildRestResultFuncForMethod(string methodName); } diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index b3f0d96c8..beddfbc10 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -48,7 +48,7 @@ public IEnumerable InterfaceHttpMethods { get { return interfaceHttpMethods.Keys; } } - public Func BuildRequestFactoryForMethod(string methodName) + public Func BuildRequestFactoryForMethod(string methodName, string basePath = "") { if (!interfaceHttpMethods.ContainsKey(methodName)) { throw new ArgumentException("Method must be defined and have an HTTP Method attribute"); @@ -64,7 +64,7 @@ public Func BuildRequestFactoryForMethod(string me setHeader(ret, header.Key, header.Value); } - var urlTarget = new StringBuilder(restMethod.RelativePath); + var urlTarget = new StringBuilder(basePath).Append(restMethod.RelativePath); var queryParamsToAdd = new Dictionary(); for(int i=0; i < paramList.Length; i++) { @@ -188,9 +188,8 @@ Func buildVoidTaskFuncForMethod(RestMethodInfo restM Func> buildTaskFuncForMethod(RestMethodInfo restMethod) where T : class { - var factory = BuildRequestFactoryForMethod(restMethod.Name); - return async (client, paramList) => { + var factory = BuildRequestFactoryForMethod(restMethod.Name, client.BaseAddress.AbsolutePath); var rq = factory(paramList); var resp = await client.SendAsync(rq); if (restMethod.SerializedReturnType == typeof(HttpResponseMessage)) { From fdcdaa751f20b36728f26ac6f45700abb96787fb Mon Sep 17 00:00:00 2001 From: Calin Date: Mon, 23 Jun 2014 20:33:16 +0300 Subject: [PATCH 4/7] buildVoidTaskFuncForMethod now takes into consideration the client absolute path --- Refit-Tests/RequestBuilder.cs | 20 ++++++++++++++++++-- Refit/RequestBuilderImplementation.cs | 5 ++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Refit-Tests/RequestBuilder.cs b/Refit-Tests/RequestBuilder.cs index 876d4d00e..f2ddc2bf4 100644 --- a/Refit-Tests/RequestBuilder.cs +++ b/Refit-Tests/RequestBuilder.cs @@ -230,9 +230,12 @@ public interface IDummyHttpApi [Get("/foo/bar/{id}")] Task FetchSomeStuffWithCustomHeader(int id, [Header("X-Emoji")] string custom); - [Get("/some")] + [Get("/string")] Task FetchSomeStuffWithoutFullPath(); + [Get("/void")] + Task FetchSomeStuffWithVoid(); + string SomeOtherMethod(); } @@ -409,7 +412,20 @@ public void HttpClientPathShouldBePrefixedToTheRequestUri() var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]); task.Wait(); - Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/some"); + Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/string"); + } + + [Test] + public void HttpClientPathForVoidMethodShouldBePrefixedToTheRequestUri() + { + var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); + var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithVoid"); + var testHttpMessageHandler = new TestHttpMessageHandler(); + + var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]); + task.Wait(); + + Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/void"); } } } \ No newline at end of file diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index beddfbc10..8024f4c22 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -174,10 +174,9 @@ public Func BuildRestResultFuncForMethod(string me } Func buildVoidTaskFuncForMethod(RestMethodInfo restMethod) - { - var factory = BuildRequestFactoryForMethod(restMethod.Name); - + { return async (client, paramList) => { + var factory = BuildRequestFactoryForMethod(restMethod.Name, client.BaseAddress.AbsolutePath); var rq = factory(paramList); var resp = await client.SendAsync(rq); From f2eef322e5da1c541ef8c64f3f5b21c81afc6dcc Mon Sep 17 00:00:00 2001 From: Calin Date: Mon, 23 Jun 2014 23:00:30 +0300 Subject: [PATCH 5/7] fixes the failing specs and adds one more test --- Refit-Tests/RequestBuilder.cs | 21 +++++++++++++++++---- Refit-Tests/RestService.cs | 3 --- Refit/RequestBuilderImplementation.cs | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Refit-Tests/RequestBuilder.cs b/Refit-Tests/RequestBuilder.cs index f2ddc2bf4..024134ef6 100644 --- a/Refit-Tests/RequestBuilder.cs +++ b/Refit-Tests/RequestBuilder.cs @@ -403,7 +403,7 @@ public void NullDynamicHeaderShouldNotBeInHeaders() } [Test] - public void HttpClientPathShouldBePrefixedToTheRequestUri() + public void HttpClientShouldPrefixedAbsolutePathToTheRequestUri() { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithoutFullPath"); @@ -412,11 +412,11 @@ public void HttpClientPathShouldBePrefixedToTheRequestUri() var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]); task.Wait(); - Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/string"); + Assert.AreEqual("http://api/foo/bar/string", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); } [Test] - public void HttpClientPathForVoidMethodShouldBePrefixedToTheRequestUri() + public void HttpClientForVoidMethodShouldPrefixedAbsolutePathToTheRequestUri() { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithVoid"); @@ -425,7 +425,20 @@ public void HttpClientPathForVoidMethodShouldBePrefixedToTheRequestUri() var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]); task.Wait(); - Assert.AreEqual(testHttpMessageHandler.RequestMessage.RequestUri.ToString(), "http://api/foo/bar/void"); + Assert.AreEqual("http://api/foo/bar/void", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); + } + + [Test] + public void HttpClientShouldNotPrefixEmptyAbsolutePathToTheRequestUri() + { + var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); + var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuff"); + var testHttpMessageHandler = new TestHttpMessageHandler(); + + var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { 42 }); + task.Wait(); + + Assert.AreEqual("http://api/foo/bar/42", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); } } } \ No newline at end of file diff --git a/Refit-Tests/RestService.cs b/Refit-Tests/RestService.cs index 130a563e2..8d4be1b3e 100644 --- a/Refit-Tests/RestService.cs +++ b/Refit-Tests/RestService.cs @@ -1,13 +1,10 @@ using System; using System.Net.Http; - using NUnit.Framework; using System.Threading.Tasks; namespace Refit.Tests { - using System.Security.Cryptography.X509Certificates; - public class User { public string login { get; set; } diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index 8024f4c22..ebc294473 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -64,7 +64,7 @@ public Func BuildRequestFactoryForMethod(string me setHeader(ret, header.Key, header.Value); } - var urlTarget = new StringBuilder(basePath).Append(restMethod.RelativePath); + var urlTarget = new StringBuilder(basePath == "/" ? String.Empty : basePath).Append(restMethod.RelativePath); var queryParamsToAdd = new Dictionary(); for(int i=0; i < paramList.Length; i++) { From 2ef50ac7226e8fd924c5e6c6f158652b1d1eb070 Mon Sep 17 00:00:00 2001 From: Calin Date: Tue, 24 Jun 2014 15:05:15 +0300 Subject: [PATCH 6/7] reset to java style formating --- Refit-Tests/RequestBuilder.cs | 36 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/Refit-Tests/RequestBuilder.cs b/Refit-Tests/RequestBuilder.cs index 024134ef6..597141e5b 100644 --- a/Refit-Tests/RequestBuilder.cs +++ b/Refit-Tests/RequestBuilder.cs @@ -55,13 +55,11 @@ public void GarbagePathsShouldThrow() { bool shouldDie = true; - try - { + try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "GarbagePath")); } - catch (ArgumentException) - { + catch (ArgumentException) { shouldDie = false; } @@ -73,13 +71,11 @@ public void MissingParametersShouldBlowUp() { bool shouldDie = true; - try - { + try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "FetchSomeStuffMissingParameters")); } - catch (ArgumentException) - { + catch (ArgumentException) { shouldDie = false; } @@ -185,13 +181,11 @@ public void SyncMethodsShouldThrow() { bool shouldDie = true; - try - { + try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "AsyncOnlyBuddy")); } - catch (ArgumentException) - { + catch (ArgumentException) { shouldDie = false; } @@ -266,33 +260,27 @@ public void MethodsThatDontHaveAnHttpMethodShouldFail() "FetchSomeStuff", }; - foreach (var v in failureMethods) - { + foreach (var v in failureMethods) { bool shouldDie = true; - try - { + try { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); } - catch (Exception ex) - { + catch (Exception ex) { shouldDie = false; } Assert.IsFalse(shouldDie); } - foreach (var v in successMethods) - { + foreach (var v in successMethods) { bool shouldDie = false; - try - { + try { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); } - catch (Exception ex) - { + catch (Exception ex) { shouldDie = true; } From e3a8e4f55880bb1ca07a80cc7d311b1861fc1ab7 Mon Sep 17 00:00:00 2001 From: Calin Date: Tue, 24 Jun 2014 15:07:48 +0300 Subject: [PATCH 7/7] places catches on the same line as { } --- Refit-Tests/RequestBuilder.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Refit-Tests/RequestBuilder.cs b/Refit-Tests/RequestBuilder.cs index 597141e5b..af4d06730 100644 --- a/Refit-Tests/RequestBuilder.cs +++ b/Refit-Tests/RequestBuilder.cs @@ -58,8 +58,7 @@ public void GarbagePathsShouldThrow() try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "GarbagePath")); - } - catch (ArgumentException) { + } catch (ArgumentException) { shouldDie = false; } @@ -74,8 +73,7 @@ public void MissingParametersShouldBlowUp() try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "FetchSomeStuffMissingParameters")); - } - catch (ArgumentException) { + } catch (ArgumentException) { shouldDie = false; } @@ -184,8 +182,7 @@ public void SyncMethodsShouldThrow() try { var input = typeof(IRestMethodInfoTests); var fixture = new RestMethodInfo(input, input.GetMethods().First(x => x.Name == "AsyncOnlyBuddy")); - } - catch (ArgumentException) { + } catch (ArgumentException) { shouldDie = false; } @@ -266,8 +263,7 @@ public void MethodsThatDontHaveAnHttpMethodShouldFail() try { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); - } - catch (Exception ex) { + } catch (Exception ex) { shouldDie = false; } Assert.IsFalse(shouldDie); @@ -279,8 +275,7 @@ public void MethodsThatDontHaveAnHttpMethodShouldFail() try { var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi)); fixture.BuildRequestFactoryForMethod(v); - } - catch (Exception ex) { + } catch (Exception ex) { shouldDie = true; }