Wednesday, December 23, 2015

Repost: Fire and Motion

Original Post: http://www.joelonsoftware.com/articles/fog0000000339.html


Joel on Software

Fire And Motion

by Joel Spolsky
Sunday, January 06, 2002
Sometimes I just can't get anything done.
Sure, I come into the office, putter around, check my email every ten seconds, read the web, even do a few brainless tasks like paying the American Express bill. But getting back into the flow of writing code just doesn't happen.
TetrisThese bouts of unproductiveness usually last for a day or two. But there have been times in my career as a developer when I went for weeks at a time without being able to get anything done. As they say, I'm not in flow. I'm not in the zone. I'm not anywhere.
Everybody has mood swings; for some people they are mild, for others, they can be more pronounced or even dysfunctional. And the unproductive periods do seem to correlate somewhat with gloomier moods.
It makes me think of those researchers who say that basically peoplecan't control what they eat, so any attempt to diet is bound to be short term and they will always yoyo back to their natural weight. Maybe as a software developer I really can't control when I'm productive, and I just have to take the slow times with the fast times and hope that they average out to enough lines of code to make me employable.

 
Go read The Onion for a while.
 
 
What drives me crazy is that ever since my first job I've realized that as a developer, I usually average about two or three hours a day of productive coding. When I had a summer internship at Microsoft, a fellow intern told me he was actually only going into work from 12 to 5 every day. Five hours, minus lunch, and his team loved him because he still managed to get a lot more done than average. I've found the same thing to be true. I feel a little bit guilty when I see how hard everybody else seems to be working, and I get about two or three quality hours in a day, and still I've always been one of the most productive members of the team. That's probably why when Peopleware and XP insist on eliminating overtime and working strictly 40 hour weeks, they do so secure in the knowledge that this won't reduce a team's output.
But it's not the days when I "only" get two hours of work done that worry me. It's the days when I can't do anything.
I've thought about this a lot. I tried to remember the time when I got the most work done in my career. It was probably when Microsoft moved me into a beautiful, plush new office with large picture windows overlooking a pretty stone courtyard full of cherry trees in bloom. Everything was clicking. For months I worked nonstop grinding out the detailed specification for Excel Basic -- a monumental ream of paper going into incredible detail covering a gigantic object model and programming environment. I literally never stopped. When I had to go to Boston for MacWorld I took a laptop with me, and documented the Window class sitting on a pleasant terrace at HBS.
Once you get into flow it's not too hard to keep going. Many of my days go like this: (1) get into work (2) check email, read the web, etc. (3) decide that I might as well have lunch before getting to work (4) get back from lunch (5) check email, read the web, etc. (6) finally decide that I've got to get started (7) check email, read the web, etc. (8) decide again that I really have to get started (9) launch the damn editor and (10) write code nonstop until I don't realize that it's already 7:30 pm.
Somewhere between step 8 and step 9 there seems to be a bug, because I can't always make it across that chasm.bike trip For me, just getting started is the only hard thing. An object at rest tends to remain at rest. There's something incredible heavy in my brain that is extremely hard to get up to speed, but once it's rolling at full speed, it takes no effort to keep it going. Like a bicycle decked out for a cross-country, self-supported bike trip -- when you first start riding a bike with all that gear, it's hard to believe how much work it takes to get rolling, but once you are rolling, it feels just as easy as riding a bike without any gear.
Maybe this is the key to productivity: just getting started. Maybe when pair programming works it works because when you schedule a pair programming session with your buddy, you force each other to get started.
Joel in the Army
When I was an Israeli paratrooper a general stopped by to give us a little speech about strategy. In infantry battles, he told us, there is only one strategy: Fire and Motion. You move towards the enemy while firing your weapon. The firing forces him to keep his head down so he can't fire at you. (That's what the soldiers mean when they shout "cover me." It means, "fire at our enemy so he has to duck and can't fire at me while I run across this street, here." It works.)  The motion allows you to conquer territory and get closer to your enemy, where your shots are much more likely to hit their target. If you're not moving, the enemy gets to decide what happens, which is not a good thing. If you're not firing, the enemy will fire at you, pinning you down.
I remembered this for a long time. I noticed how almost every kind of military strategy, from air force dogfights to large scale naval maneuvers, is based on the idea of Fire and Motion. It took me another fifteen years to realize that the principle of Fire and Motion is how you get things done in life. You have to move forward a little bit, every day. It doesn't matter if your code is lame and buggy and nobody wants it. If you are moving forward, writing code and fixing bugs constantly, time is on your side. Watch out when your competition fires at you. Do they just want to force you to keep busy reacting to their volleys, so you can't move forward?
Think of the history of data access strategies to come out of Microsoft. ODBC, RDO, DAO, ADO, OLEDB, now ADO.NET - All New! Are these technological imperatives? The result of an incompetent design group that needs to reinvent data access every goddamn year? (That's probably it, actually.) But the end result is just cover fire. The competition has no choice but to spend all their time porting and keeping up, time that they can't spend writing new features. Look closely at the software landscape. The companies that do well are the ones who rely least on big companies and don't have to spend all their cycles catching up and reimplementing and fixing bugs that crop up only on Windows XP. The companies who stumble are the ones who spend too much time reading tea leaves to figure out the future direction of Microsoft. People get worried about .NET and decide to rewrite their whole architecture for .NET because they think they have to. Microsoft is shooting at you, and it's just cover fire so that they can move forward and you can't, because this is how the game is played, Bubby. Are you going to support HailstormSOAPRDF? Are you supporting it because your customers need it, or because someone is firing at you and you feel like you have to respond? The sales teams of the big companies understand cover fire. They go into their customers and say, "OK, you don't have to buy from us. Buy from the best vendor. But make sure that you get a product that supports (XML / SOAP / CDE / J2EE) because otherwise you'll be Locked In The Trunk." Then when the little companies try to sell into that account, all they hear is obedient CTOs parrotting "Do you have J2EE?" And they have to waste all their time building in J2EE even if it doesn't really make any sales, and gives them no opportunity to distinguish themselves. It's a checkbox feature -- you do it because you need the checkbox saying you have it, but nobody will use it or needs it. And it's cover fire.
Fire and Motion, for small companies like mine, means two things. You have to have time on your side, and you have to move forward every day. Sooner or later you will win. All I managed to do yesterday is improve the color scheme in FogBUGZ just a little bit. That's OK. It's getting better all the time. Every day our software is better and better and we have more and more customers and that's all that matters. Until we're a company the size of Oracle, we don't have to think about grand strategies. We just have to come in every morning and somehow, launch the editor.
It's getting better all the time... o/~

Wednesday, December 2, 2015

Npm, AngularJS project problem and solution

1. ERROR: EACCES when running npm related command
use whoami  to check the current user, then do
sudo chown -R [username] [targetdir]


2. tar.unpack untar error
upgrade node to the latest version

Tuesday, September 8, 2015

Javascript Optimization

1. Measuring JavaScript Functions' Performance
http://www.sitepoint.com/measuring-javascript-functions-performance/?utm_source=javascriptweekly&utm_medium=email

Monday, September 7, 2015

5 Useful Mac OS X Command Line Tips Everyone Should Know (Repost)

Original Link:
http://osxdaily.com/2008/06/29/5-useful-mac-os-x-command-line-tips-you-should-know/

Like many other power users, I’m addicted to the Mac OS X command line, any reason at all for me to launch the terminal I take as an opportunity to learn more about the powerful backend of our favorite operating system.
Here I have gathered 5 useful commands that will make your life easier when you’re working in the command line interface of OS X, so launch the Terminal and try them out on your Mac! If you have any others that you think should be added to this list, feel free to post them in the comments, and be sure to check out 10 OS X Command line utilities you might not know about for more.

1: Delete an entire line of commands/text

Don’t repeatedly hit the delete key, all you need to do to clear your prompt is hit Control-U and your current prompt will be clean.

2: Create a nested directory structure immediately

If you need to create the directory structure /annoyingly/long/and/outrageous/directory/path/ , instead of typing mkdir annoyingly, cd annoyingly, mk long , etc etc, simply type the following:
mkdir -p /annoyingly/long/and/outrageous/directory/path/
And your nested directory structure will be created in full immediately!

3: Clear the entire Terminal screen

If you have a screen full of nonsense, clearing the Terminal screen is very easy, you can either type:
clear
Or you can just hit the command keystroke Control-Land you’ll have a clean slate to work with.

4: Run a process in the background

If you want to set a process to run in the background, simply put a & after it, the command will execute but you’ll still be in the same shell, allowing you to continue as usual.
For example:
./crazyscript.sh &
Would run that script in the background, and return you right back to your shell.

5: Run the last executed command

Need to re-run the last executed command? ! is the way to go, here are two ways to use it:
First, just typing:
!!
will run whatever the last command that was executed, typing
!l
will run the last command starting with the letter l, and so forth. Very useful, isn’t it?

Tuesday, August 18, 2015

What's the best way to avoid garbage collector pauses with big heaps in Java (Question excerpt from Quora)

Answered by Li Pi

https://www.quora.com/Whats-the-best-way-to-avoid-garbage-collector-pauses-with-big-heaps-in-Java

If the GC (Concurrent-Mark-Sweep) (see How does garbage collection work in the JVM?) is operating as expected, then the stop the world pauses should not be significant. CMS is designed to have as few stop the world pauses as possible. The Parallel New Collector will stop the world, but as long as your young generation is reasonably sized, you should be fine.

To recap, CMS operates by first stopping the world, then initially markingthe root nodes, then it concurrently proceeds to trace through the rest of the objects. Memory is freed at the end of this process, but objects are never moved around, making fragmentation problematic.

However, there exist a few failure modes where CMS will be forced the stop the world for a significant amount of time:

1. Concurrent Mode Failure - This occurs when the tenured generation fills up before CMS has completed it's work. When this happens, the JVM will fall back to a stop the world garbage collection mode. 

For efficiency's sake, the JVM attempts to start the garbage collection process as late as it can get away with. CMS tracks the growth in heapsize and attempts to time it's collection so that the collection ends right before the tenured generation fills up. Sometimes Java is wrong - such as if during the collection process, object tenuring rate increases dramatically.

You'll know if you're experiencing this failure mode if you see the words [CMS (concurrent mode failure): in your GC log.

If this failure mode is bugging you, simply set - XX:CMSInitiatingOccupancyFraction to a conservative value. This will tell the JVM to start garbage collection earlier, and thus, not run out of space so much.


2. Promotion Failure Due to Fragmentation:

This is the other biggie. If you see ParNew (promotion failed) in your GC log, you're experiencing this.



I'm gonna steal more content from Todd Lipcon and this blog post again:http://www.cloudera.com/blog/201...

This failure mode is a little bit more complicated. Recall that the CMS collector does not relocate objects, but simply tracks all of the separate areas of free space in the heap. As a thought experiment, imagine that I allocate 1 million objects, each 1KB, for a total usage of 1GB in a heap that is exactly 1GB. Then I free every odd-numbered object, so I have 500MB live. However, the free space will be solely made up of 1KB chunks. If I need to allocate a 2KB object, there is nowhere to put it, even though I ostensibly have 500MB of space free. This is termed memory fragmentation. No matter how early I ask the CMS collector to start, since it does not relocate objects, it cannot solve this problem!

When this problem occurs, the collector again falls back to the copying collector, which is able to compact all the objects and free up space.

Solutions:

Dealing with this failure mode is more difficult. As answerers have mentioned above, try to do things in a way that don't create garbage in the tenured generation - the new generation is always collected by a copying collector, thus fragmentation doesn't occur in the young generation.

The tenured generation makes the assumption that objects that are allocated together die together, but if we violate this tenet, fragmentation becomes a big problem. You can get around this by manually allocating memory in a way that objects next to eachother die at the same time, and can thus be collected together.

Todd Lipcon gives an awesome writeup of this approach with a Local Allocation Buffer in this blog post. http://www.cloudera.com/blog/201...

Another possible solution I'm working on at Cloudera is to move the most memory hungry elements of the application off-heap, either through the usage of DirectByteBuffers or via JNI. A slab allocation model similar to MemCached can be used in order to trade space efficiency for fragmentation overhead. 

You may either choose to manage memory manually, and copy stuff on heap when necessary, or wrap references to the external code in phantom references, and use a reference queue to keep track of which references have been garbage collected, and then free them using some form of free(). If you just need a cache, BigMemory provides a commercial, off the shelf solution. 

You're also free to rip out the allocator and cache I implemented inhttps://issues.apache.org/jira/b....

Obviously, both approaches employed by Todd and I are engineering intensive, and not simple to implement. But if GC tuning fails, and if you really want to minimize pauses with your Java/Scala/etc apps, then you might want to experiment with these approaches.

How does garbage collection work in JVM (Question excerpt from Quora)

Answered by Li Pi

https://www.quora.com/How-does-garbage-collection-work-in-the-JVM

This actually varies depending on the JVM implementation, but I'm assuming you're talking about Oracle (Sun) Version 6. Java itself does not specify a particular method of garbage collection.

The JVM uses a form of garbage collector called a tracing collector, which essentially operates by first stopping the world, marking all root objects, or objects that are referenced directly by running threads, and following references, marking each object it hits along the way.

Java 6 implements something called a generational garbage collector—based upon the generational hypothesis assumption, which states that the majority of objects that are created are quickly discarded, and that objects that are not quickly collected are likely to be around for some time.

Based upon these assumptions, Java therefore partitions objects into two different generations, and then operates differently upon them.

Visually, the generations look like this:

(Not quite to scale)
Young Generation: This is where objects start out. It has two subgenerations:
  • Eden - Objects start out here.
  • Survivor - Objects that survive Eden end up here. There are two of these, and only one is in use at any given time. One is designated as empty, and the other as live. This switched every GC cycle.

Tenured Generation: Older objects with longer lifetimes end up here.

Java is smart enough to apply different garbage collection methods to each generation. The young generation is handled using a tracingcopyingcollector called the Parallel New Collector. This collector stops the world, but because the young generation is generally small, the pause is short.

For the young generation:

When Eden fills up, the garbage collector stops the world, then traces through the objects in the young generation, starting with those referenced immediately by a running thread.

Those that are marked or "alive" are copied over to the empty survivor space. This survivor space is then marked as "live", and Eden, along with the other survivor space, is marked as empty. This has the side effect of compacting all the objects into a single survivor space, allowing for rather efficient memory usage. If an object has been copied between the two survivor places a certain amount of times, its designated as tenured, and moved to the tenured section.

Eden will now be overwritten by new objects, and the next garbage collection cycle will proceed to use the other survivor space.

This usage of a copying collector for the young generation is fast because the vast majority of objects are very quickly destroyed, and generally, very few objects must be moved around.

For the tenured generation:

I'm going to steal this section from this blog post by Todd Lipcon,http://www.cloudera.com/blog/201... 

Tenured Generation – Concurrent Mark-Sweep

Every time the parallel new collector runs, it will tenure some objects into the tenured generation. So, of course, the old generation will eventually fill up, and we need a strategy for collecting it as well. The Concurrent-Mark-Sweep collector (CMS) is responsible for clearing dead objects in this generation.

The CMS collector operates in a series of phases. Some phases stop the world, and others run concurrently with the Java application. The major phases are:
  1. initial-mark (stops the world). In this phase, the CMS collector places amark on the rootobjects. A root object is something directly referenced from a live Thread – for example, the local variables in use by that thread. This phase is short because the number of roots is very small.
  2. concurrent-mark (concurrent). The collector now follows every pointer starting from the root objects until it has marked all live objects in the system.
  3. remark (stops the world). Since objects might have had references changed, and new objects might have been created during concurrent-mark, we need to go back and take those into account in this phase. This is short because a special data structure allows us to only inspect those objects that were modified during the prior phase.
  4. concurrent-sweep (concurrent). Now, we proceed through all objects in the heap. Any object without a mark is collected and considered free space. New objects allocated during this time are marked as they are created so that they aren’t accidentally collected.

The important things to note here are:
  • The stop-the-world phases are made to be very short. The long work of scanning the whole heap and sweeping up the dead objects happens concurrently.
  • This collector does not relocate the live objects, so free space can be spread in different chunks throughout the heap. We’ll come back to this later!

Why do most software engineers use a MacBook instead of a Windows or a Linux laptop (Question excerpt from Quora)

---- Answered by Eric Zheng

https://www.quora.com/Question-That-Contains-Assumptions-1/Why-do-most-software-engineers-use-a-MacBook-instead-of-a-Windows-or-a-Linux-laptop

Several big things coincidently happened around the same time in late last decade:

  • iOS and Android - 2007-2008
  • Amazon Web Services - 2006
  • x86 MacBook and Mac OS - 2006
  • Startup booming - post 2008-2009 recession
  • Git and GitHub - 2005 (git) and 2008 (github)

Combined together, they are why MacBook is so much more popular today than a decade ago (circa 2005):

1. Mobile app

The population of iOS and Android app developers is huge. It makes a lot of sense to develop iOS and Android apps on Mac. iPhone and Android were born around 2007/2008

2. Amazon Web Services

Public cloud, especially AWS, made it much easier to provision servers. However, AWS, the leading and dominant public cloud provider launched in2006, didn't support windows in the first a couple years. It added Windows support in EC2 in 2008 as a beta feature. In the following a couple years, as far as I remember, the developer community was still staying away from running Windows on AWS because the glitches here and there. Therefore, in order to take advantage of the cloud computing, many people had no choice but start to pick up Linux.

3. Startup

Tech startups started taking off soon after the 2008-2009 recession. One of the reasons was that AWS made it much easier to do startup. Startup prefer use AWS for cost saving and other cloud computing benefits. Startup attracted many best programmers, for many reasons including the potential huge financial return. Because of having joined startups, many people started to pick up Linux. Also, good programmers make their work platform better. An example in the history was that VB/Delphi/VC++ programmers on Windows 95/98, in their side project, created a lot of great softwares to scratch their own itches, such as to download/upload files (remember those FTP clients and HTTP downloaders?), play MP3 and video (WinAmp, ...), editing text file, etc.. Similar thing happened to OS X platform in the last several years. That is the power of developer ecosystem, which helped make Windows successful.

4. OS X on x86

In 2005, Apple announced to change OS X to x86 architecture. The transition started from 2006, when Apple released the first x86 MacBook, and completed in 2009 when OS X 10.6 was released which only supported x86. 

This switch has two major impacts:

First, Mac hardware changing to x86 allowed us to install Windows on MacBook, using Boot Camp (released in 2006). That made it a lot more comfortable for people to buy a MacBook as their only personal computer. Because prior to that, although many people loved the build quality and form factor of a MacBook, they were afraid of the software issues. For example, there were a lot of websites using ActiveX which weren't very well supported on Mac OS X. Now with dual systems, they have a way out: when necessary, they can boot into the Windows.

Second, now lots of the tools that work on Linux can be much more easily ported to Mac OS X, because the tools are mostly written for x86 architecture and now OS X is also x86. Like many others said, now OS X is a much nicer Linux workstation.

5. Git and GitHub

Because git was created by the creator of Linux, git works really well on Linux. Because of git, GitHub was possible and got popular. Because of git (2005) and GitHub (2008), it became much easier to do open source, compared to the days when we only had SourceForge, CodePlex and Google Code. When it's easy to do open source projects, more open source tools and lib are created, which leads to more applications on the platform (Linux/Mac OS).



p.s. I previously partially misunderstood what the asker meant. The asker was saying that the hardware MacBook is the most popular. S/He didn't say Mac OS X was the most popular. The asker seemed to have said that many MacBook hardware is running Windows. 

Having admitted the misunderstanding, I would like to keep my above answer, since it still explains my view of why MacBook (running Mac OS X) has become very popular among developers. 

Personally I don't see many people running Windows as the primary OS on their MacBook.

Monday, August 17, 2015

The Netflix Tech Blog: Making Netflix.com Faster

The Netflix Tech Blog: Making Netflix.com Faster: by Kristofer Baxter Simply put, performance matters. We know members want to immediately start browsing or watching their favorite content ...

Tuesday, July 7, 2015

IE problems

I. Something only works after you open the developer tool (F12)


In IE9, some functions related to console are only activated when the Developer Tool is opened.
For example, the console.dir(...) doesn't work unless the Developer Tool (F12) is open.
Tosolve this problem, we just need to use console.log(...) instead of console.dir(...). 
You can try console.dir([1,2]) and console.log([1,2]) to see the difference.

Related Link:

About the console:

Difference between console.log and console.dir:

II. Back button behavior on a page with Iframe

http://www.webdeveasy.com/back-button-behavior-on-a-page-with-an-iframe/

III. How to check whether a browser is IE 11
http://stackoverflow.com/questions/17907445/how-to-detect-ie11
if (navigator.appName == 'Microsoft Internet Explorer')
  {
    // Do something
    
  }
  else if (navigator.appName == 'Netscape')
  {
    // If you are here, it means your browser is not IE10 or IE older
    if (re.exec(ua) != null)
      // If you are here, it means your browser is IE11
  }

Monday, June 15, 2015

Git on Mac

1. Set [TAB] as auto-completion
    curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash

Add the following code to file ~/.bash_profile :
if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi
Give the script permission to run:
chmod -X ~/.git-completion.bash

Close and open a new shell. Done!

Tuesday, April 21, 2015

How to test private function in Angularjs

These days, I am working on unit tests of an AngularJS application. But it drives me crazy when I encountered private functions.
I  read the two articles by Philip Walton: 
My idea was inspired from these two articles.
It seems like whether and how to test the private function in Javascript is still a controversial topic.
For me, I choose to do it. There are two reasons:
First of all, some of the code are not written by me. I'd like to play around with my test code rather than changing others' work. And we haven't decided whether it's OK to make those code public.
Second of all, there are many private functions, I don't think it's good to skip all of them.

A brief instruction of the app I am working on

The app is built with gulp. We set the task

gulp test

for unit test.

In the app code, we have the following structure :
angular.module('MainModule').controller('MainCtrl',MainController);

mainController.$injct = ['dep1','dep2']

function MainController(dep1,dep2){
  var vm = this;
  var name = '';
  var isMember = false;

  vm.somePubFuncs = function(){
    // call those private functions from public function
  }

  function updateMemberBenefitTable(){
     // dosomething here
  }

  function loadMemberBenefitTable(){
    // dosomething here
  }
}

I will test the updateMemberBenefitTable() and loadMemberBenefitTalbe().

My basic idea of testing the private functions

Adding some public interfaces for the private function at the beginning of test, and strip them at the end of the test.
I use gulp-insert-lines for adding and gulp-strip-code for stripping.

I added the comments pair
/*test-code-insert-here*/  /*end-test-code-insert-here*/
i.e.

angular.module('MainModule').controller('MainCtrl',MainController);

mainController.$injct = ['dep1','dep2']

function MainController(dep1,dep2){
  var vm = this;
  var name = '';
  var isMember = false;

  vm.somePubFuncs = function(){
    // call those private functions from public function
  }

  /*test-code-insert-here*/
  /*end-test-code-insert-here*/

  function updateMember--BenefitTable(){
     // dosomething here
  }

  function loadMemberBenefitTable(){
    // dosomething here
  }
}

The interfaces will be inserted into the pair of comments.

The gulp task for unit test is:
var insertLines = require('gulp-insert-lines');
var stripCode = require('gulp-strip-code');

gulp.task('test',function(){

  // This section is to add the interfaces of the private function into the source file
  var str = '/*--test-only*/'+'\n'+
            'vm._updateMemberBenefitTable = updateMemberBenefitTable;'+'\n'+
            'vm._loadMemberBenefitTable= loadMemberBenefitTable;'+'\n'+
            '/*--end-test-only*/';
  gulp.src('path/of/MainCtrl')
    .pipe(insertLines({
      'after':/\/\*test-code-insert-here\*\/$/,
      'lineAfter':str
    }))
    .pipe(gulp.dest('dest'));
  //END This section is to add the interfaces of the private function into the source file
  
  return gulp.src('testfile.js')
    .pipe($.karma({
      configFile: 'karma.conf.js',
      action: 'run'  
    }))
    .on('end',function(){
      // This section is to strip off the interfaces of the private function 
      //at the end of the unit test
      gulp.src('path/of.MainCtrl')
        .pipe(stripCode({
          start_comment:'--test-only',
          end_comment:'--end-test-only'
        }))
        .pipe(gulp.dest('dest')); 
      //END This section is to strip off the interfaces of the private function 
      //at the end of the unit test
}) .on('error',function(err){ throw err; })


Please keep in mind that the /*--test-only*/  /*--end-test-only*/ comments pair is very important. Because later on, when gulp-strip-code is stripping the interfaces, the comments pair will be stripped as well. If you use /*test-code-insert-here*/ /*end-test-code-insert-here*/ pair for stripping, you will end up with being not able to find them at the next run of gulp test.

Tuesday, March 31, 2015

Useful Git Command

1. Squash
Say your bug fix branch is called bugfix and you want to merge it into master:
git checkout master
git merge --squash bugfix
git commit

2. Delete unexpected stash pop
git clean -f

3. Delete remote branch (the local one has been deleted)
git push origin --delete 

4. Reset commit
git reset --hard <HEAD>
git push -f

5. How to show or change Git username
http://alvinalexander.com/git/git-show-change-username-email-address

6. Generating SSH keys
https://help.github.com/articles/generating-ssh-keys/

7. Check who is the latest person updated the branch
git for-each-ref --format='%(refname) - %(authorname) (%(committerdate))' 'refs/remotes'

8. Prune the local list of remote branches
git remote prune origin

Sunday, March 29, 2015

Unexpected request GET error in Angular JS

I got the
Error: Unexpected request: GET components/template.html
No more request expected
at $httpBackend ... 

For me, the reason for this problem is:
The relative path of template.html in karma.conf.js preprocessors, beforeEach(module) and myDirective.js are different, i.e:
in the karma.conf.js, it was:
preprocessors: {
    'src/components/template.html': ['ng-html2js']
},

in the beforeEach(module), it was:

beforeEach(module('src/components/template.html'))

and in the myDirective,js, it was:

function myDirective(){
    return{
        restrict: 'EA',
        templateUrl: 'src/components/template.html'
    };
}

To solve the problem, I change all the relative path to
'src/components/template.html'

Wednesday, March 25, 2015

Good articles about AngularJS


Basic usage
1. AngularJS code style guide
- Jhon Papa: 10 AngularJS patterns
https://www.youtube.com/watch?v=UlvCbnKAH3g
https://github.com/johnpapa/ng-demos
- Todd Motto
https://github.com/toddmotto/angularjs-styleguide
- Angular Best Practices: Directory Structure
https://scotch.io/tutorials/angularjs-best-practices-directory-structure
- Scalable code organization in AngularJS
https://medium.com/opinionated-angularjs/scalable-code-organization-in-angularjs-9f01b594bf06
- Code Organization in large AngularJS and JavaScript Applications
http://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript
2. Understanding $emit, $broadcast and $on in AngularJS
http://www.dotnet-tricks.com/Tutorial/angularjs/HM0L291214-Understanding-$emit,-$broadcast-and-$on-in-AngularJS.html
3. Recipes with Angular.js
http://fdietz.github.io/recipes-with-angular-js//controllers/testing-controllers.html
4. Angularjs directive
http://www.chroder.com/2014/02/01/using-ngmodelcontroller-with-custom-directives/
5. Controller in directive
http://www.bennadel.com/blog/2446-using-controllers-in-directives-in-angularjs.htm
6. Derictive Isolate Scope
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope
7. Understanding Dependency Injection
https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection
8. Directive's lifecycle in AngularJS
http://filimanjaro.com/2014/angular-directive-lifecycle-vs-link-compile-controller/
9. Developer Guide Recipe: Provider, Factory, Service, Constant
https://docs.angularjs.org/guide/providers
http://www.learn-angular.org/#!/lessons/the-provider-recipe


AngularJS Unit Test:
1. Introduction to Unit Testing in AngularJS App
http://www.smashingmagazine.com/2014/10/07/introduction-to-unit-testing-in-angularjs/
2. Mocking Dependencies in AngularJS Tests
http://www.sitepoint.com/mocking-dependencies-angularjs-tests/
3. spyOn and createSpy
http://www.htmlgoodies.com/html5/javascript/spy-on-javascript-methods-using-the-jasmine-testing-framework.html#fbid=e4VtfL1YKyJ
4. Unit Testing w/ AngularJS
http://moduscreate.com/unit-testing-w-angularjs/
5. How to Unit Test Controllers
http://nathanleclaire.com/blog/2013/12/13/how-to-unit-test-controllers-in-angularjs-without-setting-your-hair-on-fire/
6. AngularJS Unit Testing Best Practices
http://blog.codeship.com/angularjs-tdd/
7. Introduction to Unit Test: Directives
http://angular-tips.com/blog/2014/06/introduction-to-unit-test-directives/
8. Video: Testing Directives
https://www.youtube.com/watch?v=rB5b67Cg6bc
9. Video: Unit Testing a Directive  ---- Egghead
https://www.youtube.com/watch?v=NV5Zkthh7nw
10. Testing AngularJS directive: handling external templates
http://www.portlandwebworks.com/blog/testing-angularjs-directives-handling-external-templates
11. Unit Testing AngularJS Directives With External Templates
http://www.bluesphereinc.com/blog/unit-testing-angularjs-directives
12. Testing AngularJS directives with External Templates --- using templatecache
http://www.portlandwebworks.com/blog/testing-angularjs-directives-handling-external-templates
13. Testing AngularJS directive templates with Jasmine and Karma
http://www.portlandwebworks.com/blog/testing-angularjs-directives-handling-external-templates
14. Testing directive that appends template to element ---- stackoverflow
http://stackoverflow.com/questions/28363679/testing-directive-that-appends-template-to-element
15. When template path in templateUrl of directive.js, module(<template path>) of directive.spec.js and preprocessor of karma.conf.js are different:
https://github.com/vojtajina/ng-directive-testing/issues/3#issuecomment-87720458
http://tylerhenkel.com/how-to-test-directives-that-use-templateurl/
16. Testing AngularJS Directive with Jasmine ---- From simple to complex
http://busypeoples.github.io/post/testing-angularjs-directives/
http://busypeoples.github.io/post/testing-angularjs-hierarchical-directives/
17. Video and sample code: What, How, When to test ---- e2e, unit test, TFD
https://www.youtube.com/watch?v=9-kumGACGYk
https://github.com/auser/testing-example
18. Angular Testing Cheat Sheet
https://github.com/sydcanem/angularjs-testing-cheat-sheet
19. Change constant value that gets passed to Config for Unit Test
http://stackoverflow.com/questions/25295445/angularjs-change-constant-value-that-gets-passed-to-config-for-unit-test
20. Unit Test custom provider
http://stackoverflow.com/questions/14771810/how-to-test-angularjs-custom-provider
https://github.com/angular/angular.js/issues/2274
21. Example of testing isolate scope
http://plnkr.co/edit/QXprEUof2Ps0Vivg4L34?p=preview
http://stackoverflow.com/questions/27697747/angular-testing-directive-with-templateurl-isolate-scope
22. Introduction to Unit Test: Services
http://angular-tips.com/blog/2014/06/introduction-to-unit-test-services/
23. Writing Unit Tests for an AngularJS Service
https://busypeoples.github.io/post/writing-unit-tests-for-service-in-angular-js/
24. Supplying Mocks for Services via $provide
http://tech.pro/tutorial/1517/supplying-mocks-for-services-via-provide
25. AngularJS Unit Testing Best Practices
http://blog.codeship.com/angularjs-tdd/
26. Understanding Dependency Injection