• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import static com.google.common.truth.Truth.assertThat;
11 
12 import protobuf_unittest.Engine;
13 import protobuf_unittest.TimingBelt;
14 import protobuf_unittest.Vehicle;
15 import protobuf_unittest.Wheel;
16 import java.util.ArrayList;
17 import java.util.List;
18 import org.junit.Test;
19 import org.junit.runner.RunWith;
20 import org.junit.runners.JUnit4;
21 
22 /**
23  * Test cases that exercise end-to-end use cases involving {@link SingleFieldBuilder} and {@link
24  * RepeatedFieldBuilder}.
25  */
26 @RunWith(JUnit4.class)
27 public class NestedBuildersTest {
28 
29   @Test
test3LayerPropagationWithIntermediateClear()30   public void test3LayerPropagationWithIntermediateClear() {
31     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
32     vehicleBuilder.getEngineBuilder().getTimingBeltBuilder();
33 
34     // This step detaches the TimingBelt.Builder (though it leaves a SingleFieldBuilder in place)
35     vehicleBuilder.getEngineBuilder().clear();
36 
37     // These steps build the middle and top level messages, it used to leave the vestigial
38     // TimingBelt.Builder in a state where further changes didn't propagate anymore
39     Object unused = vehicleBuilder.getEngineBuilder().build();
40     unused = vehicleBuilder.build();
41 
42     TimingBelt expected = TimingBelt.newBuilder().setNumberOfTeeth(124).build();
43     vehicleBuilder.getEngineBuilder().setTimingBelt(expected);
44     // Testing that b/254158939 is fixed. It used to be that the setTimingBelt call above didn't
45     // propagate a change notification and the call below would return a stale version of the timing
46     // belt.
47     assertThat(vehicleBuilder.getEngine().getTimingBelt()).isEqualTo(expected);
48   }
49 
50   @Test
testMessagesAndBuilders()51   public void testMessagesAndBuilders() {
52     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
53     vehicleBuilder.addWheelBuilder().setRadius(4).setWidth(1);
54     vehicleBuilder.addWheelBuilder().setRadius(4).setWidth(2);
55     vehicleBuilder.addWheelBuilder().setRadius(4).setWidth(3);
56     vehicleBuilder.addWheelBuilder().setRadius(4).setWidth(4);
57     vehicleBuilder.getEngineBuilder().setLiters(10);
58 
59     Vehicle vehicle = vehicleBuilder.build();
60     assertThat(vehicle.getWheelCount()).isEqualTo(4);
61     for (int i = 0; i < 4; i++) {
62       Wheel wheel = vehicle.getWheel(i);
63       assertThat(wheel.getRadius()).isEqualTo(4);
64       assertThat(wheel.getWidth()).isEqualTo(i + 1);
65     }
66     assertThat(vehicle.getEngine().getLiters()).isEqualTo(10);
67 
68     for (int i = 0; i < 4; i++) {
69       vehicleBuilder.getWheelBuilder(i).setRadius(5).setWidth(i + 10);
70     }
71     Engine.Builder engineBuilder = vehicleBuilder.getEngineBuilder().setLiters(20);
72 
73     vehicle = vehicleBuilder.build();
74     for (int i = 0; i < 4; i++) {
75       Wheel wheel = vehicle.getWheel(i);
76       assertThat(wheel.getRadius()).isEqualTo(5);
77       assertThat(wheel.getWidth()).isEqualTo(i + 10);
78     }
79     assertThat(vehicle.getEngine().getLiters()).isEqualTo(20);
80     assertThat(vehicle.hasEngine()).isTrue();
81 
82     engineBuilder.setLiters(50);
83     assertThat(vehicleBuilder.getEngine().getLiters()).isEqualTo(50);
84   }
85 
86   @Test
testMessagesAreCached()87   public void testMessagesAreCached() {
88     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
89     vehicleBuilder.addWheelBuilder().setRadius(1).setWidth(2);
90     vehicleBuilder.addWheelBuilder().setRadius(3).setWidth(4);
91     vehicleBuilder.addWheelBuilder().setRadius(5).setWidth(6);
92     vehicleBuilder.addWheelBuilder().setRadius(7).setWidth(8);
93 
94     // Make sure messages are cached.
95     List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList());
96     for (int i = 0; i < wheels.size(); i++) {
97       assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i));
98     }
99 
100     // Now get builders and check they didn't change.
101     for (int i = 0; i < wheels.size(); i++) {
102       vehicleBuilder.getWheel(i);
103     }
104     for (int i = 0; i < wheels.size(); i++) {
105       assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i));
106     }
107 
108     // Change just one
109     vehicleBuilder.getWheelBuilder(3).setRadius(20).setWidth(20);
110 
111     // Now get wheels and check that only that one changed
112     for (int i = 0; i < wheels.size(); i++) {
113       if (i < 3) {
114         assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i));
115       } else {
116         assertThat(wheels.get(i)).isNotSameInstanceAs(vehicleBuilder.getWheel(i));
117       }
118     }
119   }
120 
121   @Test
testRemove_WithNestedBuilders()122   public void testRemove_WithNestedBuilders() {
123     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
124     vehicleBuilder.addWheelBuilder().setRadius(1).setWidth(1);
125     vehicleBuilder.addWheelBuilder().setRadius(2).setWidth(2);
126     vehicleBuilder.removeWheel(0);
127 
128     assertThat(vehicleBuilder.getWheelCount()).isEqualTo(1);
129     assertThat(vehicleBuilder.getWheel(0).getRadius()).isEqualTo(2);
130   }
131 
132   @Test
testRemove_WithNestedMessages()133   public void testRemove_WithNestedMessages() {
134     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
135     vehicleBuilder.addWheel(Wheel.newBuilder().setRadius(1).setWidth(1));
136     vehicleBuilder.addWheel(Wheel.newBuilder().setRadius(2).setWidth(2));
137     vehicleBuilder.removeWheel(0);
138 
139     assertThat(vehicleBuilder.getWheelCount()).isEqualTo(1);
140     assertThat(vehicleBuilder.getWheel(0).getRadius()).isEqualTo(2);
141   }
142 
143   @Test
testMerge()144   public void testMerge() {
145     Vehicle vehicle1 =
146         Vehicle.newBuilder()
147             .addWheel(Wheel.newBuilder().setRadius(1).build())
148             .addWheel(Wheel.newBuilder().setRadius(2).build())
149             .build();
150 
151     Vehicle vehicle2 = Vehicle.newBuilder().mergeFrom(vehicle1).build();
152     // List should be the same -- no allocation
153     assertThat(vehicle1.getWheelList()).isSameInstanceAs(vehicle2.getWheelList());
154 
155     Vehicle vehicle3 = vehicle1.toBuilder().build();
156     assertThat(vehicle1.getWheelList()).isSameInstanceAs(vehicle3.getWheelList());
157   }
158 
159   @Test
testGettingBuilderMarksFieldAsHaving()160   public void testGettingBuilderMarksFieldAsHaving() {
161     Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
162     vehicleBuilder.getEngineBuilder();
163     Vehicle vehicle = vehicleBuilder.buildPartial();
164     assertThat(vehicle.hasEngine()).isTrue();
165   }
166 }
167