aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2019-10-07 07:33:18 -0700
committerRob Mensching <rob@firegiant.com>2019-10-07 11:27:21 -0700
commit7e87a6b75d0570c3ebfbf0e537fcf04e1cf84224 (patch)
tree2f88738485acf07e5b1318b21b7ce2b5c06a725b
parentcece10e037c6daacc8d2def1a9057882aec47fe4 (diff)
downloadwix-7e87a6b75d0570c3ebfbf0e537fcf04e1cf84224.tar.gz
wix-7e87a6b75d0570c3ebfbf0e537fcf04e1cf84224.tar.bz2
wix-7e87a6b75d0570c3ebfbf0e537fcf04e1cf84224.zip
Support tagging tuples and definitions
-rw-r--r--src/WixToolset.Data/IntermediateTuple.cs159
-rw-r--r--src/WixToolset.Data/IntermediateTupleDefinition.cs163
-rw-r--r--src/test/WixToolsetTest.Data/SerializeFixture.cs100
-rw-r--r--src/test/WixToolsetTest.Data/TagFixture.cs101
4 files changed, 519 insertions, 4 deletions
diff --git a/src/WixToolset.Data/IntermediateTuple.cs b/src/WixToolset.Data/IntermediateTuple.cs
index bc46e3b4..8a5858ee 100644
--- a/src/WixToolset.Data/IntermediateTuple.cs
+++ b/src/WixToolset.Data/IntermediateTuple.cs
@@ -9,6 +9,8 @@ namespace WixToolset.Data
9 [DebuggerDisplay("{DebuggerDisplay,nq}")] 9 [DebuggerDisplay("{DebuggerDisplay,nq}")]
10 public class IntermediateTuple 10 public class IntermediateTuple
11 { 11 {
12 private object tags;
13
12 public IntermediateTuple(IntermediateTupleDefinition definition) : this(definition, null, null) 14 public IntermediateTuple(IntermediateTupleDefinition definition) : this(definition, null, null)
13 { 15 {
14 } 16 }
@@ -33,12 +35,132 @@ namespace WixToolset.Data
33 35
34 private string DebuggerDisplay => $"{this.Definition?.Name} {this.Id?.Id}"; 36 private string DebuggerDisplay => $"{this.Definition?.Name} {this.Id?.Id}";
35 37
38 public bool AddTag(string add)
39 {
40 if (this.tags == null)
41 {
42 this.tags = add;
43 }
44 else if (this.tags is string tag)
45 {
46 if (tag == add)
47 {
48 return false;
49 }
50
51 this.tags = new[] { tag, add };
52 }
53 else
54 {
55 var tagsArray = (string[])this.tags;
56 var array = new string[tagsArray.Length + 1];
57
58 for (var i = 0; i < tagsArray.Length; ++i)
59 {
60 if (tagsArray[i] == add)
61 {
62 return false;
63 }
64
65 array[i] = tagsArray[i];
66 }
67
68 array[tagsArray.Length] = add;
69
70 this.tags = array;
71 }
72
73 return true;
74 }
75
76 public bool HasTag(string has)
77 {
78 if (this.tags == null)
79 {
80 return false;
81 }
82 else if (this.tags is string tag)
83 {
84 return tag == has;
85 }
86 else
87 {
88 foreach (var element in (string[])this.tags)
89 {
90 if (element == has)
91 {
92 return true;
93 }
94 }
95 }
96
97 return false;
98 }
99
100 public bool RemoveTag(string remove)
101 {
102 if (this.tags is string tag)
103 {
104 if (tag == remove)
105 {
106 this.tags = null;
107 return true;
108 }
109 }
110 else if (this.tags is string[] tagsArray)
111 {
112 if (tagsArray.Length == 2)
113 {
114 if (tagsArray[0] == remove)
115 {
116 this.tags = tagsArray[1];
117 return true;
118 }
119 else if (tagsArray[1] == remove)
120 {
121 this.tags = tagsArray[0];
122 return true;
123 }
124 }
125 else
126 {
127 var array = new string[tagsArray.Length - 1];
128 var arrayIndex = 0;
129 var found = false;
130
131 for (var i = 0; i < tagsArray.Length; ++i)
132 {
133 if (tagsArray[i] == remove)
134 {
135 found = true;
136 continue;
137 }
138 else if (arrayIndex == array.Length)
139 {
140 break;
141 }
142
143 array[arrayIndex++] = tagsArray[i];
144 }
145
146 if (found)
147 {
148 this.tags = array;
149 return true;
150 }
151 }
152 }
153
154 return false;
155 }
156
36 internal static IntermediateTuple Deserialize(ITupleDefinitionCreator creator, Uri baseUri, JsonObject jsonObject) 157 internal static IntermediateTuple Deserialize(ITupleDefinitionCreator creator, Uri baseUri, JsonObject jsonObject)
37 { 158 {
38 var definitionName = jsonObject.GetValueOrDefault<string>("type"); 159 var definitionName = jsonObject.GetValueOrDefault<string>("type");
39 var idJson = jsonObject.GetValueOrDefault<JsonObject>("id"); 160 var idJson = jsonObject.GetValueOrDefault<JsonObject>("id");
40 var sourceLineNumbersJson = jsonObject.GetValueOrDefault<JsonObject>("ln"); 161 var sourceLineNumbersJson = jsonObject.GetValueOrDefault<JsonObject>("ln");
41 var fieldsJson = jsonObject.GetValueOrDefault<JsonArray>("fields"); 162 var fieldsJson = jsonObject.GetValueOrDefault<JsonArray>("fields");
163 var tagsJson = jsonObject.GetValueOrDefault<JsonArray>("tags");
42 164
43 var id = (idJson == null) ? null : Identifier.Deserialize(idJson); 165 var id = (idJson == null) ? null : Identifier.Deserialize(idJson);
44 var sourceLineNumbers = (sourceLineNumbersJson == null) ? null : SourceLineNumber.Deserialize(sourceLineNumbersJson); 166 var sourceLineNumbers = (sourceLineNumbersJson == null) ? null : SourceLineNumber.Deserialize(sourceLineNumbersJson);
@@ -54,6 +176,25 @@ namespace WixToolset.Data
54 } 176 }
55 } 177 }
56 178
179 if (tagsJson == null || tagsJson.Count == 0)
180 {
181 }
182 else if (tagsJson.Count == 1)
183 {
184 tuple.tags = (string)tagsJson[0];
185 }
186 else
187 {
188 var tags = new string[tagsJson.Count];
189
190 for (var i = 0; i < tagsJson.Count; ++i)
191 {
192 tags[i] = (string)tagsJson[i];
193 }
194
195 tuple.tags = tags;
196 }
197
57 return tuple; 198 return tuple;
58 } 199 }
59 200
@@ -86,6 +227,24 @@ namespace WixToolset.Data
86 227
87 jsonObject.Add("fields", fieldsJson); 228 jsonObject.Add("fields", fieldsJson);
88 229
230 if (this.tags is string || this.tags is string[])
231 {
232 JsonArray tagsJson;
233
234 if (this.tags is string tag)
235 {
236 tagsJson = new JsonArray(1) { tag };
237 }
238 else
239 {
240 var array = (string[])this.tags;
241 tagsJson = new JsonArray(array.Length);
242 tagsJson.AddRange(array);
243 }
244
245 jsonObject.Add("tags", tagsJson);
246 }
247
89 return jsonObject; 248 return jsonObject;
90 } 249 }
91 } 250 }
diff --git a/src/WixToolset.Data/IntermediateTupleDefinition.cs b/src/WixToolset.Data/IntermediateTupleDefinition.cs
index bc49bc7b..eb05c28b 100644
--- a/src/WixToolset.Data/IntermediateTupleDefinition.cs
+++ b/src/WixToolset.Data/IntermediateTupleDefinition.cs
@@ -7,6 +7,8 @@ namespace WixToolset.Data
7 7
8 public class IntermediateTupleDefinition 8 public class IntermediateTupleDefinition
9 { 9 {
10 private object tags;
11
10 public IntermediateTupleDefinition(string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType) 12 public IntermediateTupleDefinition(string name, IntermediateFieldDefinition[] fieldDefinitions, Type strongTupleType)
11 : this(TupleDefinitionType.MustBeFromAnExtension, name, 0, fieldDefinitions, strongTupleType) 13 : this(TupleDefinitionType.MustBeFromAnExtension, name, 0, fieldDefinitions, strongTupleType)
12 { 14 {
@@ -53,11 +55,131 @@ namespace WixToolset.Data
53 return result; 55 return result;
54 } 56 }
55 57
58 public bool AddTag(string add)
59 {
60 if (this.tags == null)
61 {
62 this.tags = add;
63 }
64 else if (this.tags is string tag)
65 {
66 if (tag == add)
67 {
68 return false;
69 }
70
71 this.tags = new[] { tag, add };
72 }
73 else
74 {
75 var tagsArray = (string[])this.tags;
76 var array = new string[tagsArray.Length + 1];
77
78 for (var i = 0; i < tagsArray.Length; ++i)
79 {
80 if (tagsArray[i] == add)
81 {
82 return false;
83 }
84
85 array[i] = tagsArray[i];
86 }
87
88 array[tagsArray.Length] = add;
89
90 this.tags = array;
91 }
92
93 return true;
94 }
95
96 public bool HasTag(string has)
97 {
98 if (this.tags == null)
99 {
100 return false;
101 }
102 else if (this.tags is string tag)
103 {
104 return tag == has;
105 }
106 else
107 {
108 foreach (var element in (string[])this.tags)
109 {
110 if (element == has)
111 {
112 return true;
113 }
114 }
115 }
116
117 return false;
118 }
119
120 public bool RemoveTag(string remove)
121 {
122 if (this.tags is string tag)
123 {
124 if (tag == remove)
125 {
126 this.tags = null;
127 return true;
128 }
129 }
130 else if (this.tags is string[] tagsArray)
131 {
132 if (tagsArray.Length == 2)
133 {
134 if (tagsArray[0] == remove)
135 {
136 this.tags = tagsArray[1];
137 return true;
138 }
139 else if (tagsArray[1] == remove)
140 {
141 this.tags = tagsArray[0];
142 return true;
143 }
144 }
145 else
146 {
147 var array = new string[tagsArray.Length - 1];
148 var arrayIndex = 0;
149 var found = false;
150
151 for (var i = 0; i < tagsArray.Length; ++i)
152 {
153 if (tagsArray[i] == remove)
154 {
155 found = true;
156 continue;
157 }
158 else if (arrayIndex == array.Length)
159 {
160 break;
161 }
162
163 array[arrayIndex++] = tagsArray[i];
164 }
165
166 if (found)
167 {
168 this.tags = array;
169 return true;
170 }
171 }
172 }
173
174 return false;
175 }
176
56 internal static IntermediateTupleDefinition Deserialize(JsonObject jsonObject) 177 internal static IntermediateTupleDefinition Deserialize(JsonObject jsonObject)
57 { 178 {
58 var name = jsonObject.GetValueOrDefault<string>("name"); 179 var name = jsonObject.GetValueOrDefault<string>("name");
59 var revision = jsonObject.GetValueOrDefault("rev", 0); 180 var revision = jsonObject.GetValueOrDefault("rev", 0);
60 var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("fields"); 181 var definitionsJson = jsonObject.GetValueOrDefault<JsonArray>("fields");
182 var tagsJson = jsonObject.GetValueOrDefault<JsonArray>("tags");
61 183
62 var fieldDefinitions = new IntermediateFieldDefinition[definitionsJson.Count]; 184 var fieldDefinitions = new IntermediateFieldDefinition[definitionsJson.Count];
63 185
@@ -69,7 +191,28 @@ namespace WixToolset.Data
69 fieldDefinitions[i] = new IntermediateFieldDefinition(fieldName, fieldType); 191 fieldDefinitions[i] = new IntermediateFieldDefinition(fieldName, fieldType);
70 } 192 }
71 193
72 return new IntermediateTupleDefinition(name, revision, fieldDefinitions, null); 194 var definition = new IntermediateTupleDefinition(name, revision, fieldDefinitions, null);
195
196 if (tagsJson == null || tagsJson.Count == 0)
197 {
198 }
199 else if (tagsJson.Count == 1)
200 {
201 definition.tags = (string)tagsJson[0];
202 }
203 else
204 {
205 var tags = new string[tagsJson.Count];
206
207 for (var i = 0; i < tagsJson.Count; ++i)
208 {
209 tags[i] = (string)tagsJson[i];
210 }
211
212 definition.tags = tags;
213 }
214
215 return definition;
73 } 216 }
74 217
75 internal JsonObject Serialize() 218 internal JsonObject Serialize()
@@ -103,6 +246,24 @@ namespace WixToolset.Data
103 246
104 jsonObject.Add("fields", fieldsJson); 247 jsonObject.Add("fields", fieldsJson);
105 248
249 if (this.tags is string || this.tags is string[])
250 {
251 JsonArray tagsJson;
252
253 if (this.tags is string tag)
254 {
255 tagsJson = new JsonArray(1) { tag };
256 }
257 else
258 {
259 var array = (string[])this.tags;
260 tagsJson = new JsonArray(array.Length);
261 tagsJson.AddRange(array);
262 }
263
264 jsonObject.Add("tags", tagsJson);
265 }
266
106 return jsonObject; 267 return jsonObject;
107 } 268 }
108 } 269 }
diff --git a/src/test/WixToolsetTest.Data/SerializeFixture.cs b/src/test/WixToolsetTest.Data/SerializeFixture.cs
index 527359fe..221ca19c 100644
--- a/src/test/WixToolsetTest.Data/SerializeFixture.cs
+++ b/src/test/WixToolsetTest.Data/SerializeFixture.cs
@@ -55,7 +55,7 @@ namespace WixToolsetTest.Data
55 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool), 55 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
56 }; 56 };
57 57
58 var tupleDef = new IntermediateTupleDefinition("CustomDef", fieldDefs, null); 58 var tupleDef = new IntermediateTupleDefinition("CustomDef2", fieldDefs, null);
59 59
60 var tuple = tupleDef.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT")); 60 var tuple = tupleDef.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT"));
61 tuple.Set(0, "foo"); 61 tuple.Set(0, "foo");
@@ -119,7 +119,93 @@ namespace WixToolsetTest.Data
119 new IntermediateFieldDefinition("D", IntermediateFieldType.String), 119 new IntermediateFieldDefinition("D", IntermediateFieldType.String),
120 }; 120 };
121 121
122 var tupleDef2 = new IntermediateTupleDefinition("CustomDef", 1, fieldDefs2, null); 122 var tupleDef2 = new IntermediateTupleDefinition("CustomDef2", 1, fieldDefs2, null);
123
124 var tuple2 = tupleDef2.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT2"));
125 tuple2.Set(0, "bar");
126 tuple2.Set(1, 3);
127 tuple2.Set(2, false);
128 tuple2.Set(3, "baz");
129
130 var section2 = new IntermediateSection("test2", SectionType.Fragment, 65001);
131 section2.Tuples.Add(tuple2);
132
133 var intermediate2 = new Intermediate("TestIntermediate2", new[] { section2 }, null, null);
134
135 // Save
136 var path1 = Path.GetTempFileName();
137 var path2 = Path.GetTempFileName();
138 try
139 {
140 intermediate1.Save(path1);
141 intermediate2.Save(path2);
142
143 var loaded = Intermediate.Load(new[] { path1, path2 });
144
145 var loaded1 = loaded.First();
146 var loaded2 = loaded.Skip(1).Single();
147
148 var loadedTuple1 = loaded1.Sections.Single().Tuples.Single();
149 var loadedTuple2 = loaded2.Sections.Single().Tuples.Single();
150
151 Assert.Equal("foo", loadedTuple1.AsString(0));
152 Assert.Equal(2, loadedTuple1[1].AsNumber());
153 Assert.True(loadedTuple1[2].AsBool());
154
155 Assert.Equal("bar", loadedTuple2.AsString(0));
156 Assert.Equal(3, loadedTuple2[1].AsNumber());
157 Assert.False(loadedTuple2[2].AsBool());
158 Assert.Equal("baz", loadedTuple2.AsString(3));
159 }
160 finally
161 {
162 File.Delete(path2);
163 File.Delete(path1);
164 }
165 }
166
167 [Fact]
168 public void CanSaveAndLoadMultipleIntermediateWithCustomDefinitionsAndTags()
169 {
170 var sln = new SourceLineNumber("test.wxs", 1);
171
172 // Intermediate #1
173 var fieldDefs = new[]
174 {
175 new IntermediateFieldDefinition("A", IntermediateFieldType.String),
176 new IntermediateFieldDefinition("B", IntermediateFieldType.Number),
177 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
178 };
179
180 var tupleDef = new IntermediateTupleDefinition("CustomDef", fieldDefs, null);
181
182 tupleDef.AddTag("customDef");
183
184 var tuple = tupleDef.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT"));
185 tuple.Set(0, "foo");
186 tuple.Set(1, 2);
187 tuple.Set(2, true);
188
189 tuple.AddTag("tuple1tag");
190
191 var section = new IntermediateSection("test", SectionType.Product, 65001);
192 section.Tuples.Add(tuple);
193
194 var intermediate1 = new Intermediate("TestIntermediate", new[] { section }, null, null);
195
196 // Intermediate #2
197 var fieldDefs2 = new[]
198 {
199 new IntermediateFieldDefinition("A", IntermediateFieldType.String),
200 new IntermediateFieldDefinition("B", IntermediateFieldType.Number),
201 new IntermediateFieldDefinition("C", IntermediateFieldType.Bool),
202 new IntermediateFieldDefinition("D", IntermediateFieldType.String),
203 };
204
205 var tupleDef2 = new IntermediateTupleDefinition("CustomDef2", 1, fieldDefs2, null);
206
207 tupleDef2.AddTag("customDef2");
208 tupleDef2.AddTag("customDef2 tag2");
123 209
124 var tuple2 = tupleDef2.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT2")); 210 var tuple2 = tupleDef2.CreateTuple(sln, new Identifier(AccessModifier.Public, "customT2"));
125 tuple2.Set(0, "bar"); 211 tuple2.Set(0, "bar");
@@ -127,6 +213,9 @@ namespace WixToolsetTest.Data
127 tuple2.Set(2, false); 213 tuple2.Set(2, false);
128 tuple2.Set(3, "baz"); 214 tuple2.Set(3, "baz");
129 215
216 tuple2.AddTag("tuple2tag1");
217 tuple2.AddTag("tuple2tag2");
218
130 var section2 = new IntermediateSection("test2", SectionType.Fragment, 65001); 219 var section2 = new IntermediateSection("test2", SectionType.Fragment, 65001);
131 section2.Tuples.Add(tuple2); 220 section2.Tuples.Add(tuple2);
132 221
@@ -148,15 +237,20 @@ namespace WixToolsetTest.Data
148 var loadedTuple1 = loaded1.Sections.Single().Tuples.Single(); 237 var loadedTuple1 = loaded1.Sections.Single().Tuples.Single();
149 var loadedTuple2 = loaded2.Sections.Single().Tuples.Single(); 238 var loadedTuple2 = loaded2.Sections.Single().Tuples.Single();
150 239
240 Assert.True(loadedTuple1.Definition.HasTag("customDef"));
151 Assert.Equal("foo", loadedTuple1.AsString(0)); 241 Assert.Equal("foo", loadedTuple1.AsString(0));
152 Assert.Equal(2, loadedTuple1[1].AsNumber()); 242 Assert.Equal(2, loadedTuple1[1].AsNumber());
153 Assert.True(loadedTuple1[2].AsBool()); 243 Assert.True(loadedTuple1[2].AsBool());
154 Assert.Null(loadedTuple1.AsString(3)); 244 Assert.True(loadedTuple1.HasTag("tuple1tag"));
155 245
246 Assert.True(loadedTuple2.Definition.HasTag("customDef2"));
247 Assert.True(loadedTuple2.Definition.HasTag("customDef2 tag2"));
156 Assert.Equal("bar", loadedTuple2.AsString(0)); 248 Assert.Equal("bar", loadedTuple2.AsString(0));
157 Assert.Equal(3, loadedTuple2[1].AsNumber()); 249 Assert.Equal(3, loadedTuple2[1].AsNumber());
158 Assert.False(loadedTuple2[2].AsBool()); 250 Assert.False(loadedTuple2[2].AsBool());
159 Assert.Equal("baz", loadedTuple2.AsString(3)); 251 Assert.Equal("baz", loadedTuple2.AsString(3));
252 Assert.True(loadedTuple2.HasTag("tuple2tag1"));
253 Assert.True(loadedTuple2.HasTag("tuple2tag2"));
160 } 254 }
161 finally 255 finally
162 { 256 {
diff --git a/src/test/WixToolsetTest.Data/TagFixture.cs b/src/test/WixToolsetTest.Data/TagFixture.cs
new file mode 100644
index 00000000..4c0426a0
--- /dev/null
+++ b/src/test/WixToolsetTest.Data/TagFixture.cs
@@ -0,0 +1,101 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolsetTest.Data
4{
5 using WixToolset.Data;
6 using Xunit;
7
8 public class TagFixture
9 {
10 [Fact]
11 public void CanAddSingleTag()
12 {
13 var tuple = TupleDefinitions.File.CreateTuple();
14 Assert.True(tuple.AddTag("test"));
15 Assert.True(tuple.HasTag("test"));
16 }
17
18 [Fact]
19 public void CanAddDuplicateTag()
20 {
21 var tuple = TupleDefinitions.File.CreateTuple();
22 Assert.True(tuple.AddTag("test"));
23 Assert.False(tuple.AddTag("test"));
24 }
25
26 [Fact]
27 public void CanAddRemoveSingleTag()
28 {
29 var tuple = TupleDefinitions.File.CreateTuple();
30 Assert.True(tuple.AddTag("test"));
31 Assert.True(tuple.RemoveTag("test"));
32 Assert.False(tuple.HasTag("test"));
33 }
34
35 [Fact]
36 public void CanAddMultipleTags()
37 {
38 var tuple = TupleDefinitions.File.CreateTuple();
39 Assert.True(tuple.AddTag("test1"));
40 Assert.True(tuple.AddTag("test2"));
41 Assert.True(tuple.HasTag("test1"));
42 Assert.True(tuple.HasTag("test2"));
43 }
44
45 [Fact]
46 public void CanAddRemoveMultipleTags()
47 {
48 var tuple = TupleDefinitions.File.CreateTuple();
49 Assert.True(tuple.AddTag("test1"));
50 Assert.True(tuple.AddTag("test2"));
51 Assert.True(tuple.RemoveTag("test2"));
52 Assert.False(tuple.HasTag("test2"));
53 Assert.True(tuple.RemoveTag("test1"));
54 Assert.False(tuple.HasTag("test1"));
55 }
56
57 [Fact]
58 public void CanAddRemoveMissingTags()
59 {
60 var tuple = TupleDefinitions.File.CreateTuple();
61 Assert.True(tuple.AddTag("test1"));
62 Assert.True(tuple.AddTag("test2"));
63 Assert.False(tuple.RemoveTag("test3"));
64 }
65
66 [Fact]
67 public void CanAdd2AndRemoveAllTags()
68 {
69 var tuple = TupleDefinitions.File.CreateTuple();
70 Assert.True(tuple.AddTag("test1"));
71 Assert.True(tuple.AddTag("test2"));
72 Assert.True(tuple.RemoveTag("test1"));
73 Assert.True(tuple.RemoveTag("test2"));
74 }
75
76 [Fact]
77 public void CanAdd3AndRemoveAllTags()
78 {
79 var tuple = TupleDefinitions.File.CreateTuple();
80 Assert.True(tuple.AddTag("test1"));
81 Assert.True(tuple.AddTag("test2"));
82 Assert.True(tuple.AddTag("test3"));
83 Assert.True(tuple.RemoveTag("test1"));
84 Assert.True(tuple.RemoveTag("test3"));
85 Assert.True(tuple.RemoveTag("test2"));
86 }
87
88 [Fact]
89 public void CanAdd3AndRemoveMissingTags()
90 {
91 var tuple = TupleDefinitions.File.CreateTuple();
92 Assert.True(tuple.AddTag("test1"));
93 Assert.True(tuple.AddTag("test2"));
94 Assert.True(tuple.AddTag("test3"));
95 Assert.False(tuple.RemoveTag("test4"));
96 Assert.True(tuple.RemoveTag("test1"));
97 Assert.True(tuple.RemoveTag("test3"));
98 Assert.True(tuple.RemoveTag("test2"));
99 }
100 }
101}