lepffm / issuance Goto Github PK
View Code? Open in Web Editor NEWBlogging with Github Issues.
Home Page: https://github.com/lepffm/issuance/issues
License: MIT License
Blogging with Github Issues.
Home Page: https://github.com/lepffm/issuance/issues
License: MIT License
Excalidraw | Hand-drawn look & feel • Collaborative • Secure
Object.assign(targetObject, ...sourceObject ) <- if it conflict same key, update sourceObject value )
// create new object
const newObject = Object.assign({}, obj1, obj2)
cf) nested object not safe.
use spread operator
const newObject = {...obj1, ...obj2};
성공하고 싶다면 ‘역산 스케줄링’ 연습하라 | 자기계발 | DBR
https://dbr.donga.com/article/view/1303/article_no/5776/ac/magazine
from https://stackoverflow.com/questions/333682/unit-testing-anti-patterns-catalogue
webClient nonProxyHosts rule.
default : "localhost|127.*|[::1]|0.0.0.0|[::0]"
so if you want to ignore proxy for some sub domain, set '*.parentdomain' or 'subdomain.parentdomain'
직접 .parentdomain 을 추가하면 정규식 오류가 발생함.
관련이슈
대신 ..patrentdomain 형식으로 등록해야함.
cf) reactor-netty v1.0.14 부터는 system property 로부터 가져오는 것으로 보임....
배경
mockmvc를 이용한 단위테스트를 작성중
모든 메소드에 권한과 관련된 예외처리가 포함되어 있어 라인 커버리지 100% 달성을 위해서는 메소드마다 예외코드로 진입하는 테스트가 필요했다.
구현과정
uri를 일일이 얻기 귀찮아 annotation에서 가져오고 required parameter도 추가
( 메소드 타입에 따라 requestparam과 content 에 기본값 설정)
cf) @Valid를 사용한 사용자 클래스는 적용불가(클래스 import가 필요함)
이거 한개 클래스만 대상으로 할 필요도 없겠다 싶은 생각.
컨트롤러 클래스만 추가하면
모든 rest 메소드에 대해서 한번은 실행시킬수 있다는 것을 알게 되었다.
(메소드 커버리지 100% 달성)
하지만 라인 커버리지는 참담 했다. 메소드당 1라인 수준
좀더 향상시킬 수 있는 방법을 고민하고 있으면서 한편 이런걸 만드는게 옳은 일인가 싶은 생각도...
테스트 커버리지를 조직 달성목표에 포함시키면 이런 쪽의 머리만 커진다...
unit testing: principals, practices and patterns
unit test
테스트 단위를 클래스로 한정할 경우의 문제점
unit test anti pattern
naming: 도메인 전문가나 비개발자에게 시나리오를 설명하듯이
cf) 메서드이름을 포함하면 결합도와 유지보수성이 나빠진다. 예외는 유틸리티 코드
parameterized test guide
테스트가 제품코드의 기능을 나열하지 않도록
비즈니스 담당자에게도 의미가 있는 고수준의 명세를 작성하라
good unit test
mock: command, 부작용o, no return
stub: query, 부작용x, has return
app service test: use case test
domain class test: sub purpose test
test style
code type
humble object pattern 으로 복잡한 코드 제거하기
e.g., humble controller, factory class
biz와 orchestration 분리가 효과적인 경우
단계가 명확하지 않은 경우의 전략
컨트롤러 복잡도 완화하기
비즈니스로직이 도메인 모델에서 유출되지 않도록 canExcute/execute 패턴 사용
e.g., 컨트롤러는 canExecute오 여부 검사, execute 메소드 초반에 canExcute를 전제조건으로 배치
도메인 이벤트로 변경사항 추적
e.g., 메일발송등 발송여부 체크를 컨트롤러에서 할경우 파편화문제 발생 -> 외부에 통보하는데 필요한 데이터를 포함한 이벤트 값을 누적(과거시제로 명명) EmailChangedEvent
cf) about abstract class test
Abstract classes are implementation details, similar to private methods
타시스템과 공유하는 테이블은 메세지 역할을 하므로 mock이 바람직
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
...
static {
Logger rootLogger = Logger.getLogger("");
Handler[] handlers = rootLogger.getHandlers();
if (handlers.length>0){
rootLogger.removeHandler(handlers[0]);
}
Logger.getGlobal().setLevel(Level.OFF);
}
vue file must declared extension
import xxx from 'xxxx.vue' ( not 'xxxx' )
env variable
use import.meta.env object
VITE_SOME_KEY=123
process.env 사용 불가 (비호환)
반대로 webpack에서는 imprt.meta 룰 구문오류로 인식함
참조모듈이 많으면 로딩 시간도 길어짐...
configure: (proxy,opt) => {
proxy.on('proxyReq', function(proxyReq,req,res){
console.log('proxyReq url : '+ req.url + ' ' + res);
res.writeHead(200,{'Content-Type':'application/json'});
res.write('{id:hi}')
res.end()
res.finished = true
});
proxy.on('proxyRes', function(pres, req, res){
});
proxy.on('error', function(pres,req,res){
});
}
IntelliJ IDEA Linux version 2021.02.04
use directory
A) flat : keep the folder hierarchy as flat as possible , redundancy of keywords in filenames/directory
B) group by domain : separate module(==domain) in case of considering microfrontend
tests/unit tests/e2e or component와 같은 위치
links
https://dev.to/vcpablo/vuejs-one-more-way-of-structuring-your-project-13mj -> vscode 및 template setting
https://docs.vuestorefront.io/v2/getting-started/project-structure.html
https://markus.oberlehner.net/blog/vue-project-directory-structure-keep-it-flat-or-group-by-domain/
https://velog.io/@cindy-choi/VUE-%EC%9A%B0%EC%95%84%ED%95%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0-%EC%A7%9C%EA%B8%B0
https://vueschool.io/articles/vuejs-tutorials/how-to-structure-a-large-scale-vue-js-application/
Random.GG - Randomizer for Everything
^(?!\s)
(?<!\s)$
[\u3131-\u314e\u314f-\u3163\uac00-\ud7a3]
\w
/^(?!\s)[\w\u3131-\u314e\u314f-\u3163\uac00-\ud7a3-.\s]{3,50}(?<!\s)$/i
time machine
git reflog
git reset HEAD@{index}
too small change commit..
// amend
// after adding your other changes
git commit --amend --no-edit
commit message update
git commit --amend
accidentally commit wrong branch
git reset HEAD~ --soft // undo last commit , leave changes
git stash
git switch correct-branch
git stash pop
git add . && git commit ...
undo commit
git log
git revert [saved hash]
git fetch with prune
remove dangling reference
git fetch --all --prune --tags --force
set global
git config --global fetch.prune true
gitconfig setup
[alias]
br = branch -vv
l = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit
la = log --all --oneline --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit
f = fetch --prune
si = switch
단순 위임 method의 test가 의미가 없다면,
호출 검증은 어떨까?
assertAll -> assertSoftly
field injection -> use apply
@tags(
Tag("slow"),
Tag("logarithms")
)
@ParameterizedTest(name = "isPalindrome should return true for {0}")
@ValueSource(strings = ["Bob", "racecar", "Malayalam", ""])
fun `Function isPalindrome returns true for Palindromes`(candidate: String) {
assertTrue(isPalindrome(candidate))
}
읽기 쉬운 문장으로 고쳐 쓰기 | naradesign.github.io
create test class
declare subject
declare mocks
add setup method
add first empty test method
execute test with coverage
comment current coverages
choice method from subject will be test( priority: biz impact and change-needed)
find happy case and choice major verification events
edit test method name with 'given conditions.., when method name, then expect result'
write test method call
write verification or assertion
while success
run (it will raise fail or error)
fix with conditions or parameters
test code refactoring
keep same level
use constants
use factory for test dataset
group same method tests with Nested
run until success
run with coverage
comment changed coverage (60>)
server level error page customizing
<error-page>
<error-code>404</error-code>
<location>/error/404.html</location>
</error-page>
2-2) or use value
https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Error_Report_Valve
<Valve className="org.apache.catalina.valves.ErrorReportValve"
showReport="false"
showServerInfo="false"
errorCode.0="webapps/examples/error.html"/>
2-3) or {Application}/WEB-INF/web.xml
(!) highest order
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
webapp
WEB_INF/jsp/erros/
@RequestMapping("/error")
https://www.baeldung.com/spring-boot-custom-error-page
{{ $data }}
test instance lifecycle modes.
PER_CLASS : a new test instance will be created once per test class.
PER_METHOD : per test method ( default )
set junit-platform.properties src/test/resources
junit.jupiter.testinstance.lifecycle.default = per_class
https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle
infinite loop : for /l %g in () do @ ( cmd ... )
wait every 1 second : use timeout /t 1
remove wait message : > null
e.g) for /l %g in () do @( curl -s google.com | findstr hello & timeout /t 1 > null )
maven cache clean
mvn dependency:purge-local-repository
show dependency
mvn dependency:tree
https://developer.mozilla.org/ko/docs/Learn/CSS/First_steps/Getting_started
.classname {}
tagname.classname {}
tag1.classname , tag2.classname {} // comman means or
tag innerTag {} // space means inner side
tag1 + nextSiblingTag {} // tag1 바로 아래 sibleingTag 에 적용
tag:state {} // state : hover, link, visited,
selector > childSelector {} // only 1depth children
#1 cascade : 마지막이 우선함
#2 class > element
margin border padding content
$base-color: #c6538c;
.xclass { border: 1px solid $base-color; }
BEM ( Block Element, Modifier )
block , block__elem , block--mod
e.g) .form , .form__input , .form__input--disabled , .form--simple
position: fixed or sticky
default flex-direction : row
이탈하지 않도록 flex-wrap: wrap;
flex: 200px >> 최소 200px 너비 지정
https://developer.mozilla.org/ko/docs/Learn/CSS/CSS_layout/Grids
display: grid; // make grid style
grid-template-columns: 70px 1fr 50px; // 3 column min70px, rate 1x , min 50px
grid-auto-rows: 100px; // grid cell height 100px
grid-gap: 20px; // grid간 column, row margin
dream 성장 미국 탄광 nasa rocket
특수문자 모음 - 기계인간 John Grib
winget - see https://winstall.app/
MobaXterm
wox # alt+space
everything
notepad++
chrome
chrome - ublacklist plugin
우아콘 2022 10월 19일 ~ 10월 21일
고품격 Kotlin 개발: 테스트 코드를 우아하게 작성하는 방법 / 박재성(제이슨) https://woowacon.com/detailVideo/19
우리 팀의 코드리뷰 문화, 이렇게 조금씩 발전했어요 / 배민스토어웹프론트개발팀 https://woowacon.com/detailVideo/29
this is issue 5
shallowCopy vs deepCopy
shallow copy : use object spread operator
const myShallowCopy = {...myOriginal};
changing nested value affects both original and copied objects.
deep copy
A) use lodash _.cloneDeep(obj)
B) use parse+strinify
const myDeepCopy = JSON.parse(JSON.stringify(myOriginal));
C) structuredClone
const myDeepCopy = structuredClone(myOriginal);
https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
list /products
create /products/create
view /products/:id
edit /products/:id/edit
https://www.nightprogrammer.com/vue-js/architect-structure-large-scale-vue-js-application-example/
mocking + when
val mockVo = mockk<MockYourVo>(relaxed = true) {
every { className } returns mockClassName
every { properties } returns emptyList()
}
mockkConstructor(T::class)
anyConstructed<T>() 로 사용
doNothing or return Unit or justRun
C >= B > A
val mockedFile = mockk<File>()
A) doNothing().`when`(mockedFile).write(any())
B) every { mockedFile.write(any()) } returns Unit
C) justRun { mockedFile.write(any()) }
A) use slot or MutableList
val personSlot = slot<Person>()
every { mockPhone.call(capture(personSlot)) } returns Unit
assertEquals("Sarah Jane", personSlot.captured.name)
B) use withArg
every { mockPhone.call( withArg { person ->
assertEquals("Jane", person.name)
})
} ...
verify(exactly = 3) { mockedFile.read() } // times(3)
verify(inverse = true) { mockedFile.write() } // never
when, thenReturn , thenThrow, thenAnswer => every {block} , returns , throws , answers
thenReturn, thenReturn => returns , andThen andThen ... andThenThrows
assertTrue(res.xx)
assertEquals(res.str, "")
}
case handing
https://marco-cattaneo.medium.com/kotlin-unit-testing-with-mockk-91d52aea2852
test class + per-class + use init + @nested grouping
helper function for object creation
fun createTestVO (name: String = "cat") = MyVo(id = 1, name: name)
// val vo1 = createTestVO() ; val vo2 = createTestVO(name="FOX")
verify{ mick.mtd(withArg{ assertEquals("expected",it.prop)}) }
verify{mock.mtd(match{it.prop == "expected"})}
you have to use ofType
every { something(ofType<B>()) } returns 1
companion object {
cons val TEST_ID = "testId"
}
Assertions.assertThatThrownBy{
// assert code
}.hasMessage("error messge") // or .hasMessageContaining("contained message")
private val modelMapper = mockk<ModelMapper>(relaxed=true)
...
every{ modelMapper.map(any<CXXDto.Response>(),any(Class<XXDto.Response>>()) returns XXDto.Response()
private field setProperty not supported. use ReflectionTestUtils of spring test library
ReflectionTestUtils.setField(subject, "privateFieldName", "value")
Felienne Hermans
knowledge LTM long term memory - keyword
information STM short - method,variable name
processing working memory
stm limit: 7+-2
‘use chunk’ ( eg word)
read < see
design pattern
comment
beacon (표식) : line or codes / simple, compounded
minimize interruption
use flash card - grammer, concept searching
elaboration 정교화
기존 기억과 연관짓기
인지부조화 줄이기
refactoring, 익숙한 것으로 대치하기, 동의어 추가
기억보조수단
dependency grapg , state table
role of variable
fixed value
stepper
flag
walker
most recent holder
most wanted holder
gatherer
container
follower
organizer
temporary
find focal point
expand knowledge from focal point
understand concept from related objects
understand concepts from other related objects
text reading
visualizing: see/hear/feel the screen?
monitoring for meaning: re-read or skip, help
question:
determining importance:
predicting /inferring
summarizing
activating relevant, prior knowledge: before, during and after reading
step for making mental model
use project lexicon
페이텔슨 모델
lapd: linguistic anti pattern detector
generally, Nested 는 method 단위로 나눈는것을 소개한다.
but grouping을 concern 단위로 정리한다고 보면,
domain/category 별로 나누는게 낫지않을까 고민...
대신 Tag로 나누는게 좋아보인다.
IntelliJ -> Test Kind // select Category
자바스크립트 Date에 locale
git clone ...
git checkout --orphan newbranch
git add -A
git commit -am 'init'
git branch -D org-branch
git branch -m org-branch
git push -f origin org-branch
Hemingway Editor
“”” raw string $var “””
kotlin compile enhancement
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
from https://kotlinlang.org/docs/maven.html#incremental-compilation
ExecutorService 를 사용하여 별도의 스레드로 실행시키는 메소드를 테스트 할 경우
다른 스레드로 실행되므로 테스트 시 정상적인 리턴값을 받아오지 못하는 문제가 발생함.
replace ExecutorService field to MoreExecutors.newDirectExecutorService()
if the filed is declared Bean then use @mock annotation.
but it just declared normal field, you must use ReflectionTestUtils of Spring Framework
// Test Target
public class YourService {
private static ExecutorService executor = Executors.newFixedThreadPool(5);
public void start(List<YourVO> vos) {
vos.forEach(vo -> executor.execute(() ->
{ ..... } // do something
)
);
}
// Test Code
import com.google.common.util.concurrent.MoreExecutors;
import org.springframework.test.util.ReflectionTestUtils;
// if static field
ReflectionTestUtils.setField(YourService.class,"executor", MoreExecutors.newDirectExecutorService());
// if not static field
ReflectionTestUtils.setField(yourServiceInstance.class,"executor", MoreExecutors.newDirectExecutorService());
on idea.properties file
idea.cycle.buffer.size=10240
Settings > Appearance & Behavior > System Settings > Reopen project on startup ( uncheck )
HELP > Edit Custom VM Options ?
-Xms2g
-Xmx2g
menu : File > Settings 또는 Ctrl+Alt+s
search "Server Certificates"
'+' click then select your.crt file , next apply
Settings | Build, Execution, Deployment | Build Tools | Gradle | Build and run
run tests using : gradle → intellij IDEA
https://github.com/forge/roaster
import org.apache.commons.text.StringEscapeUtils;
import org.jboss.forge.roaster.Roaster;
JavaClassSource javaClass =
Roaster.parse(JavaClassSource.class, "public class SomeClass {}");
System.out.println(javaClass.toString());
...
String notes = "utf-8 string" + "\\n"; // **** use \\n , not \n for unescapeJava
annotation.setStringValue("notes", notes);
...
// if you need unescape java string ( misconsidered encoding issue )
String unescaped = StringEscapeUtils.unescapeJava(javaClass.toString());
netstat -nao | findstr LISTEN | findstr 8080
tasklist /fi "PID eq XXXX"
taskill /PID XXXX /F
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.