Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
HYH.APSJ
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
佟礼
HYH.APSJ
Commits
a6cb038c
Commit
a6cb038c
authored
Sep 21, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: expand related routings through multi-level BOM
parent
ded51bc0
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
205 additions
and
58 deletions
+205
-58
MacroPlannerDataConverter.java
.../com/aps/macroplanner/data/MacroPlannerDataConverter.java
+68
-58
MacroPlannerBomLoadingTest.java
...com/aps/macroplanner/data/MacroPlannerBomLoadingTest.java
+137
-0
No files found.
src/main/java/com/aps/macroplanner/data/MacroPlannerDataConverter.java
View file @
a6cb038c
This diff is collapsed.
Click to expand it.
src/test/java/com/aps/macroplanner/data/MacroPlannerBomLoadingTest.java
0 → 100644
View file @
a6cb038c
package
com
.
aps
.
macroplanner
.
data
;
import
com.aps.entity.RoutingHeader
;
import
com.aps.entity.Routingsupporting
;
import
com.aps.mapper.RoutingHeaderMapper
;
import
com.aps.mapper.RoutingsupportingMapper
;
import
com.baomidou.mybatisplus.core.MybatisConfiguration
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.TableInfoHelper
;
import
org.apache.ibatis.builder.MapperBuilderAssistant
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Timeout
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
java.lang.reflect.Constructor
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.*;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
Mockito
.*;
class
MacroPlannerBomLoadingTest
{
private
MacroPlannerDataConverter
converter
;
private
RoutingHeaderMapper
headers
;
private
RoutingsupportingMapper
inputs
;
private
Object
context
;
@BeforeEach
void
setUp
()
throws
Exception
{
TableInfoHelper
.
initTableInfo
(
new
MapperBuilderAssistant
(
new
MybatisConfiguration
(),
"bom-test"
),
RoutingHeader
.
class
);
TableInfoHelper
.
initTableInfo
(
new
MapperBuilderAssistant
(
new
MybatisConfiguration
(),
"bom-test"
),
Routingsupporting
.
class
);
converter
=
new
MacroPlannerDataConverter
();
headers
=
mock
(
RoutingHeaderMapper
.
class
);
inputs
=
mock
(
RoutingsupportingMapper
.
class
);
ReflectionTestUtils
.
setField
(
converter
,
"routingHeaderMapper"
,
headers
);
ReflectionTestUtils
.
setField
(
converter
,
"routingsupportingMapper"
,
inputs
);
Class
<?>
contextType
=
Class
.
forName
(
MacroPlannerDataConverter
.
class
.
getName
()
+
"$ConvertContext"
);
Constructor
<?>
constructor
=
contextType
.
getDeclaredConstructor
();
constructor
.
setAccessible
(
true
);
context
=
constructor
.
newInstance
();
ReflectionTestUtils
.
setField
(
context
,
"routingHeaders"
,
new
ArrayList
<>(
Collections
.
singletonList
(
header
(
1
,
"A"
))));
}
@Test
@Timeout
(
5
)
void
eachLevelLoadsOnlyNewRoutingIds
()
{
List
<
Set
<
Object
>>
queriedRoutes
=
new
ArrayList
<>();
when
(
inputs
.
selectList
(
any
())).
thenAnswer
(
call
->
{
Set
<
Object
>
ids
=
values
(
call
.
getArgument
(
0
));
ids
.
remove
(
0
);
queriedRoutes
.
add
(
ids
);
if
(
ids
.
equals
(
Collections
.
singleton
(
1
)))
return
Collections
.
singletonList
(
input
(
1
,
"B"
));
if
(
ids
.
equals
(
Collections
.
singleton
(
2
)))
return
Collections
.
singletonList
(
input
(
2
,
"C"
));
return
Collections
.
emptyList
();
});
when
(
headers
.
selectList
(
any
())).
thenAnswer
(
call
->
values
(
call
.
getArgument
(
0
)).
contains
(
"B"
)
?
Collections
.
singletonList
(
header
(
2
,
"B"
))
:
Collections
.
emptyList
());
Set
<
String
>
materials
=
new
HashSet
<>(
Collections
.
singleton
(
"A"
));
List
<
Integer
>
result
=
ReflectionTestUtils
.
invokeMethod
(
converter
,
"expandRoutingHeaders"
,
context
,
materials
);
assertEquals
(
Arrays
.
asList
(
1
,
2
),
result
);
assertEquals
(
Arrays
.
asList
(
Collections
.
singleton
(
1
),
Collections
.
singleton
(
2
)),
queriedRoutes
);
assertEquals
(
new
HashSet
<>(
Arrays
.
asList
(
"A"
,
"B"
,
"C"
)),
materials
);
verify
(
headers
,
times
(
2
)).
selectList
(
any
());
}
@Test
@Timeout
(
5
)
void
cyclicBomTerminatesWithoutDiscardingReachableHeaders
()
{
when
(
inputs
.
selectList
(
any
())).
thenAnswer
(
call
->
values
(
call
.
getArgument
(
0
)).
contains
(
1
)
?
Collections
.
singletonList
(
input
(
1
,
"B"
))
:
Collections
.
singletonList
(
input
(
2
,
"A"
)));
when
(
headers
.
selectList
(
any
())).
thenReturn
(
Collections
.
singletonList
(
header
(
2
,
"B"
)));
List
<
Integer
>
result
=
ReflectionTestUtils
.
invokeMethod
(
converter
,
"expandRoutingHeaders"
,
context
,
new
HashSet
<>(
Collections
.
singleton
(
"A"
)));
assertEquals
(
Arrays
.
asList
(
1
,
2
),
result
);
verify
(
inputs
,
times
(
2
)).
selectList
(
any
());
verify
(
headers
,
times
(
1
)).
selectList
(
any
());
}
@Test
void
duplicateChildHeadersAreLoadedOnlyOnce
()
{
when
(
inputs
.
selectList
(
any
())).
thenReturn
(
Arrays
.
asList
(
input
(
1
,
"B"
),
input
(
1
,
"B"
)),
Collections
.
emptyList
());
when
(
headers
.
selectList
(
any
())).
thenReturn
(
Arrays
.
asList
(
header
(
2
,
"B"
),
header
(
2
,
"B"
),
header
(
3
,
"B"
)));
List
<
Integer
>
result
=
ReflectionTestUtils
.
invokeMethod
(
converter
,
"expandRoutingHeaders"
,
context
,
new
HashSet
<>(
Collections
.
singleton
(
"A"
)));
assertEquals
(
Arrays
.
asList
(
1
,
2
,
3
),
result
);
verify
(
headers
,
times
(
1
)).
selectList
(
any
());
verify
(
inputs
,
times
(
2
)).
selectList
(
any
());
}
@Test
void
nullInputMaterialDoesNotProduceUnboundedHeaderQuery
()
{
when
(
inputs
.
selectList
(
any
())).
thenReturn
(
Collections
.
singletonList
(
input
(
1
,
null
)));
List
<
Integer
>
result
=
ReflectionTestUtils
.
invokeMethod
(
converter
,
"expandRoutingHeaders"
,
context
,
new
HashSet
<>(
Collections
.
singleton
(
"A"
)));
assertEquals
(
Collections
.
singletonList
(
1
),
result
);
verifyNoInteractions
(
headers
);
}
@Test
void
oracleInGroupsAreBoundedDeduplicatedAndParenthesized
()
{
List
<
Integer
>
ids
=
IntStream
.
range
(
1
,
2002
).
boxed
().
collect
(
Collectors
.
toList
());
ids
.
add
(
1
);
LambdaQueryWrapper
<
RoutingHeader
>
wrapper
=
MacroPlannerDataConverter
.
whereIn
(
RoutingHeader:
:
getId
,
ids
);
String
predicate
=
wrapper
.
getSqlSegment
();
assertEquals
(
2001
,
wrapper
.
getParamNameValuePairs
().
size
());
assertEquals
(
3
,
predicate
.
split
(
" IN "
,
-
1
).
length
-
1
);
assertEquals
(
2
,
predicate
.
split
(
" OR "
,
-
1
).
length
-
1
);
java
.
util
.
regex
.
Matcher
groups
=
java
.
util
.
regex
.
Pattern
.
compile
(
" IN [(]([^)]+)[)]"
).
matcher
(
predicate
);
List
<
Integer
>
sizes
=
new
ArrayList
<>();
while
(
groups
.
find
())
sizes
.
add
(
groups
.
group
(
1
).
split
(
","
).
length
);
assertEquals
(
Arrays
.
asList
(
1000
,
1000
,
1
),
sizes
);
wrapper
.
eq
(
RoutingHeader:
:
getIsDeleted
,
false
);
assertTrue
(
wrapper
.
getSqlSegment
().
contains
(
") AND is_deleted ="
));
assertTrue
(
MacroPlannerDataConverter
.
whereIn
(
RoutingHeader:
:
getId
,
Collections
.
emptyList
())
.
getSqlSegment
().
contains
(
"1 = 0"
));
}
private
Set
<
Object
>
values
(
LambdaQueryWrapper
<?>
wrapper
)
{
wrapper
.
getSqlSegment
();
return
new
HashSet
<>(
wrapper
.
getParamNameValuePairs
().
values
());
}
private
RoutingHeader
header
(
int
id
,
String
material
)
{
RoutingHeader
header
=
new
RoutingHeader
();
header
.
setId
(
id
);
header
.
setMaterialId
(
material
);
return
header
;
}
private
Routingsupporting
input
(
int
routingId
,
String
material
)
{
Routingsupporting
input
=
new
Routingsupporting
();
input
.
setRoutingHeaderId
(
routingId
);
input
.
setMaterialId
(
material
);
return
input
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment